<template>
  <div
    class="annotation-container"
    v-loading="loading"
    element-loading-text="loading..."
    element-loading-background="rgba(0, 0, 0, 0)"
  >
    <div style="display: flex; width: 100%; height: 100%">
      <div class="annotation-svg-container" ref="containerRef" :style="svgContainerStyle">
        <div
          :style="{
            position: 'relative',
            overflow: 'hidden',
            width: '100%',
            height: '100%',
          }"
          @mousedown="startDrag"
          @mousemove="onDrag"
          @mouseup="endDrag"
          @mouseleave="endDrag"
          @touchstart="startDrag"
          @touchmove="onDrag"
          @touchend="endDrag"
          @touchcancel="endDrag"
          @wheel="onWheel"
        >
          <div
            class="rect--3OiK-"
            ref="svgCanvasParent"
            style="
              transform: rotate(0deg) translate3d(0px, 0px, 0px);
              position: absolute;
              right: 0;
              left: 0;
              z-index: 10;
              height: 100%;
            "
          >
            <svg
              ref="svgCanvas"
              :width="canvasWidth"
              :height="canvasHeight"
              @mousedown.capture="onMouseDown"
              @mousemove="onMouseMove"
              @mouseup="onMouseUp"
              :style="svgStyle"
            >
              <!-- @wheel="handleWheel" -->
              <image
                :width="canvasWidth"
                :height="canvasHeight"
                v-if="!loading"
                x="0"
                y="0"
                :href="realUrl"
              />
            </svg>

            <div
              v-if="tooltip.show"
              :style="{
                top: tooltip.y + 'px',
                left: tooltip.x + 'px',
                color: tooltip.color,
              }"
              class="tooltip"
            >
              {{ tooltip.text }}
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import {
  ref,
  reactive,
  onMounted,
  watch,
  onUnmounted,
  computed,
  nextTick,
  defineProps,
  defineEmits,
  defineExpose,
} from "vue";
import polylabel from "polylabel";
import SVG, { get } from "svg.js";
import svgDraw from "svg.draw.js";
import "svg.draggable.js";
import "svg.resize.js";
import "svg.select.js";
import { v4 as uuidv4 } from "uuid";
import ResizeObserver from "resize-observer-polyfill";
const props = defineProps({
  data: {
    type: Array,
    default: () => [],
  },
  batchRectList: {
    type: Map,
    default: () => new Map(),
  },
  mouseOperationType: {
    type: [Number, String],
    default: "mouseSelect", // mouseSelect: 鼠标操作, batchSelect: 批量操作
  },
  srcUrl: {
    type: String,
    default: "",
  },
  maxHistory: {
    type: Number,
    default: 10,
  },
  shortcutConfig: {
    type: Object,
    default: () => ({
      readRangeMarker: {
        key: "n",
        fill: "#ef4c4c",
      },
      unReadRangeMarker: {
        key: "r",
        fill: "#40ff40",
      },
    }),
  },

  imageScale: {
    type: [Number, String],
    default: "1",
  },
});

const emits = defineEmits([
  "update:data",
  "update:mouseOperationType",
  "update:imageScale",
  "update:batchRectList",
]);

// 鼠标操作类型
const operationType = computed({
  get() {
    console.log("props.mouseOperationType--", props.mouseOperationType);

    return props.mouseOperationType;
  },
  set(val) {
    emits("update:mouseOperationType", val);
  },
});

// ==================== 响应式数据 ====================
const currentShape = ref("rect"); // 当前选择的绘制形状类型
const drawingMode = ref(false); // 是否处于绘制模式
const drawing = ref(false); // 是否正在绘制状态
const dragging = ref(false); // 是否正在拖拽状态
const svgDoc = ref(null); // SVG.js 文档对象
const currentElement = ref(null); // 当前正在绘制的元素
const svgCanvasParent = ref(null); // SVG DOM 引用
const svgCanvas = ref(null); // SVG DOM 引用
const isSvgDragging = ref(false); // svg是否拖动
const isSvgMouseDown = ref(false); // svg是否按下
const startPoint = ref(null); // 绘制起始点坐标
const selectedElement = ref(null); // 当前选中的元素
const hoveredElement = ref(null); // 当前悬停的元素
const allElements = ref([]); // 所有已绘制的元素数组
const lastMousePos = ref({ x: 0, y: 0 }); // 上次鼠标位置（用于优化悬停检测）

const containerRef = ref(null);
// 重新定义画布尺寸相关的响应式数据
const canvasWidth = ref(800); // SVG画布宽度
const canvasHeight = ref(600); // SVG画布高度
const imageAspectRatio = ref(1); // 图片宽高比

const containerWidth = ref(800); // 容器宽度（固定）
const containerHeight = ref(1000); // 容器高度（固定）

// const batchOperationRectList = ref(new Map()) // 批量操作列表

const batchOperationRectList = computed({
  get() {
    console.log("props.batchRectList--", props.batchRectList);

    return props.batchRectList;
  },
  set(val) {
    emits("update:batchRectList", val);
  },
});

const tooltip = reactive({
  show: false,
  text: "",
  x: 0,
  y: 0,
  color: "",
});
const currentRect = computed(() => {
  if (!hoveredElement.value) return null;
  return rectList.value.find(
    (item) => item.id === hoveredElement.value.data("elementId")
  );
});

const updateTooltip = () => {
  if (currentRect.value) {
    tooltip.show = true;
    tooltip.text = currentRect.value.fieldName;

    // const rectElementRect = hoveredElement.value.node.getBoundingClientRect()
    const rect = hoveredElement.value.node.getBoundingClientRect();
    const wrapperRect = svgCanvasParent.value.getBoundingClientRect();

    // 相对 svgWrapper 的坐标
    tooltip.x = rect.left - wrapperRect.left;
    tooltip.y = rect.top - wrapperRect.top;
    tooltip.color = getDefaultStroke(hoveredElement.value);
    // tooltip.x = rectElementRect.left
    // tooltip.y = rectElementRect.top
  } else {
    tooltip.show = false;
    tooltip.text = "";
    tooltip.x = 0;
    tooltip.y = 0;
    tooltip.color = "";
  }
};
// 设置文本样式

watch(
  [currentRect, hoveredElement],
  (newVal) => {
    // if (newVal[0]) {
    //   tooltip.show = true
    //   tooltip.text = newVal[0].fieldName

    //   const rectElementRect = hoveredElement.value.node.getBoundingClientRect()
    //   tooltip.x = rectElementRect.left
    //   tooltip.y = rectElementRect.top
    //   tooltip.color = getDefaultStroke(hoveredElement.value)
    // } else {
    //   tooltip.show = false
    //   tooltip.text = ''
    //   tooltip.x = 0
    //   tooltip.y = 0
    // }
    updateTooltip();
  },
  { deep: true }
);

// 清除多选框
const clearBatchOperationRectList = () => {
  allElements.value?.forEach((rectElement) => {
    const elementId = rectElement.data("elementId");
    const rect = rectList.value.find((item) => item.id == elementId);
    if (batchOperationRectList.value.has(elementId)) {
      batchOperationRectList.value.delete(elementId);
      rectElement.attr({
        fill: getDefaultFill(rectElement),
      });
    }
  });

  batchOperationRectList.value?.clear();
};

const batchOperationRectKeyList = computed(() => {
  const keyList = [];
  if (batchOperationRectList.value?.size) {
    batchOperationRectList.value.forEach((_, key) => {
      keyList.push(key);
    });
  }
  return keyList;
});

const settingMsg = computed(() => {
  return {
    ...props.shortcutConfig,
    batchOpacity: 0.4,
  };
});

const currentImageScale = computed({
  get() {
    console.log("props.imageScale--", props.imageScale);

    return props.imageScale;
  },
  set(val) {
    emits("update:imageScale", val);
  },
}); // 当前页面显示图片与原图缩放比

const selectSettingMsg = ref({}); // 绘制的矩形类型配置
const rectType = ref(""); // 绘制的矩形类型（是否读取类型）

// 计算SVG容器的样式 - 固定容器尺寸
const svgContainerStyle = computed(() => ({
  width: `100%`,
  height: `100%`,
  maxWidth: "100%",
}));

// 历史操作记录

const historyOperationList = reactive({
  undoStack: [], // 撤销操作列表
  redoStack: [], // 取消撤销操作列表
});
function deepClone(obj) {
  return JSON.parse(JSON.stringify(obj));
}

/**
 * 更新元素状态，处理删除、更新和新增操作
 * @param {Array} targetList 目标状态列表
 * @param {Array} allElements 当前所有元素列表
 * @param {Object} svgDoc SVG文档对象
 * @param {Object} settingMsg 设置信息对象
 */
const updateElements = (targetList, allElements, svgDoc, settingMsg) => {
  const targetMap = new Map(targetList.map((item) => [item.id, item]));
  const ids = Array.from(targetMap.keys());
  let updateElement = null;
  let updateType = null;

  // 使用 splice 处理删除操作
  for (let i = allElements.value.length - 1; i >= 0; i--) {
    const item = allElements.value[i];
    const eleId = item.data("elementId");
    if (!ids.includes(eleId)) {
      hideResizeHandles(item);
      item.remove();
      if (hoveredElement.value && hoveredElement.value.data("elementId") == eleId) {
        hoveredElement.value = null;
      }
      if (selectElement.value && selectElement.value.data("elementId") == eleId) {
        selectElement.value = null;
      }
      updateType = "delete";

      allElements.value.splice(i, 1);
    }
  }

  // 处理更新操作
  allElements.value.forEach((item) => {
    const eleId = item.data("elementId");
    const rectItem = targetMap.get(eleId);
    const oldItem = {
      x: item.attr("x"),
      y: item.attr("y"),
      width: item.attr("width"),
      height: item.attr("height"),
    };
    if (
      rectItem &&
      (oldItem.x != rectItem.x ||
        oldItem.y != rectItem.y ||
        oldItem.width != rectItem.width ||
        oldItem.height != rectItem.height)
    ) {
      updateElement = item;
      updateType = "update";

      console.log("我是更新updateElement", rectItem);

      item.attr({
        x: rectItem.x,
        y: rectItem.y,
        width: rectItem.width,
        height: rectItem.height,
      });
      updateResizeHandlesPosition(item);
    }
  });

  // 处理新增操作
  targetList.forEach((rectItem) => {
    if (!allElements.value.some((item) => item.data("elementId") === rectItem.id)) {
      const rect = svgDoc.value.rect(rectItem.width, rectItem.height);
      if (updateElement) {
        updateElement = rect;
        updateType = "add";
      }
      console.log("我是新增updateElement");
      rect.attr({
        x: rectItem.x,
        y: rectItem.y,
        id: rectItem.id,
        fill: hexToRgb(settingMsg.value[rectItem.rectType].fill),
        stroke: settingMsg.value[rectItem.rectType].fill,
        strokeWidth: 1,
      });
      console.log("我已经新增updateElement");
      rect.draggable(true);
      rect.type = "rect";
      rect.data("elementId", rectItem.id);
      if (targetList.length == 1) {
        addResizeHandles(rect);
      }
      allElements.value.push(rect);
    }
  });
  return { updateElement, updateType };
};
// 撤销
const undoLastAction = () => {
  console.log("undoLastAction--");
  if (historyOperationList.undoStack.length === 0) return;

  const prev = historyOperationList.undoStack.pop();
  historyOperationList.redoStack.push(deepClone(rectList.value));

  const prevList = deepClone(prev);
  console.log("prevList--", prevList);
  rectList.value = prevList;
  nextTick(() => {
    updateElements(prevList, allElements, svgDoc, settingMsg);
  });
};

// 取消撤销
const cancelUndo = () => {
  console.log("cancelUndo--");
  if (historyOperationList.redoStack.length > 0) {
    console.log("historyOperationList.redoStack--", historyOperationList.redoStack);
    const nextState = historyOperationList.redoStack.pop();
    historyOperationList.undoStack.push(deepClone(rectList.value));
    if (historyOperationList.undoStack.length > props.maxHistory)
      historyOperationList.undoStack.shift();
    const nextList = deepClone(nextState);

    rectList.value = nextList;
    updateElements(nextList, allElements, svgDoc, settingMsg);
  }
};
const copyElement = ref(null);
// 复制元素
const copyElementHandle = () => {
  if (hoveredElement.value) {
    copyElement.value = rectList.value.find((item) => {
      return item.id == hoveredElement.value.data("elementId");
    });
    console.log("copyElement.value--", copyElement.value);

    // copyElement.id = uuidv4();
  }
};
// 黏贴元素
const pasteElementHandle = () => {
  if (copyElement.value) {
    console.log("copyElement.value--", copyElement.value);
    const { x: currentX, y: currentY } = currentMouseSvgPosition.value;
    console.log("currentX--", currentX);
    console.log("currentY--", currentY);

    const { width, height, rectType, fieldName, desc, formatType } = copyElement.value;
    const rect = svgDoc.value.rect(width, height);
    const id = uuidv4();
    rect
      .attr({
        x: currentX - width / 2,
        y: currentY - height / 2,
        id: id,
        fill: hexToRgb(settingMsg.value[rectType].fill),
        stroke: settingMsg.value[rectType].fill,
        strokeWidth: 1,
      })
      .style("cursor", "move"); // 恢复拖拽功能;
    rect.draggable(true);
    rect.type = "rect";
    rect.data("elementId", id);
    rect.data("rectType", rectType);
    allElements.value.push(rect);
    addRectList(rect, {
      fieldName,
      desc,
      formatType,
    });
    // 设置默认选中
    handleHoverPreview(
      {
        x: currentX - width / 2,
        y: currentY - height / 2,
      },
      rect
    );
    copyElement.value = null;
  }
};

// 性能优化：全局调试开关
window.debugMode = false; // 设置为 true 可以启用详细日志

// 缩放和拖动相关状态
const viewport = ref({
  scale: 1,
  translateX: 0,
  translateY: 0,
  isPanning: false,
  lastPanPoint: { x: 0, y: 0 },
  minScale: 0.1,
  maxScale: 10,
});

const minRectSize = 6; // 最小矩形尺寸

const realUrl = computed(() => {
  if (props.srcUrl.startsWith("@/")) {
    // 把 @ 转换成 src 绝对路径
    const path = props.srcUrl.replace(/^@/, "/src");
    return new URL(path, import.meta.url).href;
  }
  return props.srcUrl;
});

// ==================== 工具函数 ====================

function hexToRgb(hex, alpha = 0.1) {
  // 去除可能存在的 # 前缀
  hex = hex.replace(/^#/, "");

  // 处理简写形式，如 #fff
  if (hex.length === 3) {
    hex = hex
      .split("")
      .map((c) => c + c)
      .join("");
  }

  // 解析十六进制值
  const bigint = parseInt(hex, 16);
  const r = (bigint >> 16) & 255;
  const g = (bigint >> 8) & 255;
  const b = bigint & 255;

  // 返回 rgba 格式字符串
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}

/**
 * 获取鼠标在SVG中的准确坐标
 * @param {MouseEvent} event - 鼠标事件对象
 * @returns {{x: number, y: number}} SVG坐标系中的坐标
 */
const getMousePosition = (event) => {
  // 添加安全检查
  if (!svgCanvas.value) {
    console.error("❌ svgCanvas 未初始化");
    return { x: 0, y: 0 };
  }

  try {
    const rect = svgCanvas.value.getBoundingClientRect();

    // 验证 rect 的有效性
    if (!rect || typeof rect.left !== "number" || typeof rect.top !== "number") {
      console.error("❌ 无效的 getBoundingClientRect 结果:", rect);
      return { x: 0, y: 0 };
    }

    // SVG.js 拖拽事件可能使用不同的事件对象格式
    let clientX, clientY;

    if (event.clientX !== undefined && event.clientY !== undefined) {
      // 标准 DOM 事件
      clientX = event.clientX;
      clientY = event.clientY;
    } else if (event.detail && event.detail.event) {
      // SVG.js 拖拽事件
      clientX = event.detail.event.clientX;
      clientY = event.detail.event.clientY;
    } else if (event.originalEvent) {
      // jQuery 事件
      clientX = event.originalEvent.clientX;
      clientY = event.originalEvent.clientY;
    } else {
      // 尝试其他可能的属性
      console.warn("⚠️ 无法获取鼠标坐标，尝试其他属性:", event);

      // 检查事件对象的所有属性
      for (let key in event) {
        if (key.includes("client") || key.includes("page") || key.includes("screen")) {
          console.log(`🔍 事件属性 ${key}:`, event[key]);
        }
      }

      // 如果都找不到，使用事件对象的其他坐标
      if (event.pageX !== undefined && event.pageY !== undefined) {
        clientX = event.pageX - window.pageXOffset;
        clientY = event.pageY - window.pageYOffset;
      } else {
        console.error("❌ 无法获取鼠标坐标");
        return { x: 0, y: 0 };
      }
    }

    // 计算相对于SVG容器的坐标
    let x = clientX - rect.left;
    let y = clientY - rect.top;

    // 正确的逆变换：
    x = x / scale.value;
    y = y / scale.value;

    // 验证计算结果
    if (isNaN(x) || isNaN(y)) {
      return { x: 0, y: 0 };
    }
    // console.log("{ x, y }", { x, y });

    return { x, y };
  } catch (error) {
    console.error("❌ 获取鼠标位置时出错:", error);
    return { x: 0, y: 0 };
  }
};

/**
 * 获取元素的默认描边颜色
 * @param {Object} element - SVG元素对象
 * @returns {string} 颜色值
 */
const getDefaultStroke = (element) => {
  // console.log("element1---", element);

  const type = element.type;
  if (type === "rect") {
    if (element.data("elementId")) {
      // console.log('rectList.value---', rectList.value)
      const currentRect = rectList.value.find(
        (item) => item.id == element.data("elementId")
      );

      return settingMsg.value[currentRect.rectType].fill;
    }
  }
  if (type === "ellipse") return "green";
  if (type === "polygon") return "red";
  return "black";
};

/**
 * 获取元素的默认填充颜色
 * @param {Object} element - SVG元素对象
 * @returns {string} 颜色值
 */
const getDefaultFill = (element, alpha = 0.1) => {
  const type = element.type;

  if (type === "rect") {
    if (element.data("elementId")) {
      const currentRect = rectList.value.find(
        (item) => item.id == element.data("elementId")
      );
      // console.log('currentRect---', currentRect)

      return hexToRgb(settingMsg.value[currentRect.rectType].fill, alpha);
    }
  }
  if (type === "ellipse") return "rgba(0, 128, 0, 0.1)";
  if (type === "polygon") return "rgba(255, 0, 0, 0.1)";
  return "rgba(0, 0, 0, 0.1)";
};

// ==================== SVG.js插件验证 ====================

/**
 * 验证SVG.js插件是否正确加载
 */
const validateSVGPlugins = () => {
  console.log("🔍 验证SVG.js插件加载状态...");

  // 检查SVG.js核心
  if (typeof SVG !== "undefined") {
    console.log("✅ SVG.js 核心已加载");

    // 检查draggable插件
    if (SVG.Element.prototype.draggable) {
      console.log("✅ SVG.js draggable 插件已加载");
      console.log("draggable方法:", typeof SVG.Element.prototype.draggable);
    } else {
      console.error("❌ SVG.js draggable 插件未加载");
    }

    // 检查resize插件
    if (SVG.Element.prototype.resize) {
      console.log("✅ SVG.js resize 插件已加载");
    } else {
      console.error("❌ SVG.js resize 插件未加载");
    }

    // 检查select插件
    if (SVG.Element.prototype.select) {
      console.log("✅ SVG.js select 插件已加载");
    } else {
      console.error("❌ SVG.js select 插件未加载");
    }

    // 检查draw插件
    if (SVG.Element.prototype.draw) {
      console.log("✅ SVG.js draw 插件已加载");
    } else {
      console.error("❌ SVG.js draw 插件未加载");
    }
  } else {
    console.error("❌ SVG.js 核心未加载");
  }

  // 检查全局对象
  console.log("全局SVG对象:", window.SVG);
  console.log("SVG.Element原型:", SVG.Element.prototype);
};

/**
 * 恢复所有元素的正常拖拽状态
 */
const restoreNormalDragState = () => {
  // 优化：只在必要时清理无效元素

  // 简化循环，减少不必要的操作
  allElements.value.forEach((el) => {
    if (el && el.node && document.contains(el.node)) {
      try {
        el.draggable();
        el.data("dragPriority", false);

        // 设置拖动样式
        el.style("cursor", "move");
      } catch (error) {
        // 静默处理错误，避免影响性能
      }
    }
  });
};

// ==================== 简化的控制点系统 ====================

/**
 * 为元素添加调整大小的控制点
 * @param {Object} element - SVG元素对象
 */
const addResizeHandles = (element) => {
  // 安全检查：确保元素存在且有效
  if (!element) {
    console.warn("⚠️ addResizeHandles: element 为 null 或 undefined");
    return;
  }

  // 检查元素的 node 属性是否存在
  if (!element.node) {
    console.warn("⚠️ addResizeHandles: element.node 为 null，元素可能已被删除");
    return;
  }

  // 检查元素是否仍然在DOM中
  if (!document.contains(element.node)) {
    console.warn("⚠️ addResizeHandles: 元素已不在DOM中");
    return;
  }

  // debugger
  // 先清除之前的控制点
  hideResizeHandles(element);

  // 检查是否已经有控制点
  if (element.data("resizeHandlesCount")) {
    console.log("元素已有控制点，跳过创建");
    return;
  }

  const type = element.type;
  let bbox;

  if (type === "rect") {
    bbox = {
      x: element.x(),
      y: element.y(),
      width: element.width(),
      height: element.height(),
    };
  }

  if (!bbox) return;

  // 创建8个控制点
  const handles = [];
  const handleSize = 8; // 增加缩放点大小，提高交互体验

  // 角落控制点
  const corners = [
    { x: bbox.x, y: bbox.y, cursor: "nw-resize", class: "nw" },
    { x: bbox.x + bbox.width, y: bbox.y, cursor: "ne-resize", class: "ne" },
    { x: bbox.x, y: bbox.y + bbox.height, cursor: "sw-resize", class: "sw" },
    {
      x: bbox.x + bbox.width,
      y: bbox.y + bbox.height,
      cursor: "se-resize",
      class: "se",
    },
  ];

  // 边缘控制点
  const edges = [
    { x: bbox.x + bbox.width / 2, y: bbox.y, cursor: "n-resize", class: "n" },
    {
      x: bbox.x + bbox.width / 2,
      y: bbox.y + bbox.height,
      cursor: "s-resize",
      class: "s",
    },
    {
      x: bbox.x + bbox.width,
      y: bbox.y + bbox.height / 2,
      cursor: "e-resize",
      class: "e",
    },
    { x: bbox.x, y: bbox.y + bbox.height / 2, cursor: "w-resize", class: "w" },
  ];

  // 获取元素ID，避免在闭包中引用element对象
  const elementId = element.data("elementId");
  console.log("hideResizeHandles33");
  [...corners, ...edges].forEach((pos, index) => {
    const handle = svgDoc.value

      .circle(handleSize / 2) // 使用 circle 方法创建圆形，半径为 handleSize 的一半
      .attr({
        cx: pos.x, // 圆心 x 坐标
        cy: pos.y, // 圆心 y 坐标
        fill: "#ffffff",
        stroke: getDefaultStroke(element),
        "stroke-width": 1, // 原始边框宽度
      })
      .style("cursor", pos.cursor)
      .draggable();
    handle.front();
    handle.on("mouseenter", function (event) {
      console.log("我移入进来了");
      // 获取原始边框宽度
      const originalStrokeWidth = this.attr("stroke-width");
      const originalR = this.attr("r");
      this.attr({
        r: originalR * 1.2,
        // 边框宽度扩大为原来的 1.5 倍，可按需调整
        "stroke-width": originalStrokeWidth * 1.5, // 原始边框宽度
      });
    });

    handle.on("mouseleave", function (event) {
      console.log("我移出了");
      // 获取当前边框宽度
      const currentStrokeWidth = this.attr("stroke-width");
      const currentR = this.attr("r");
      this.attr({
        r: currentR / 1.2,
        // 边框宽度恢复为原来大小
        "stroke-width": currentStrokeWidth / 1.5, // 原始边框宽度
      });
    });

    // 使用正确的事件名称绑定拖拽事件
    handle.on("dragstart", function (event) {
      console.log("🎯 控制点拖拽开始:", pos.class);
      console.log("🔍 拖拽开始事件对象:", {
        type: event.type,
        keys: Object.keys(event),
        detail: event.detail,
        originalEvent: event.originalEvent,
      });

      // 阻止事件冒泡和默认行为
      if (event.stopPropagation) event.stopPropagation();
      if (event.preventDefault) event.preventDefault();

      dragging.value = true;

      // 重新获取当前元素的边界框，确保数据是最新的
      let currentBbox;
      if (element.type === "rect") {
        currentBbox = {
          x: element.x(),
          y: element.y(),
          width: element.width(),
          height: element.height(),
        };
      } else if (element.type === "ellipse") {
        const cx = element.cx();
        const cy = element.cy();
        const rx = element.rx();
        const ry = element.ry();
        currentBbox = {
          x: cx - rx,
          y: cy - ry,
          width: rx * 2,
          height: ry * 2,
        };
      }

      // 存储开始时的边界框和鼠标位置
      this.data("startBbox", currentBbox);
      this.data("startMousePos", getMousePosition(event));
      this.data("handleClass", pos.class);
      this.data("elementId", elementId);
    });

    handle.on("dragmove", function (event) {
      // 使用 requestAnimationFrame 优化性能，减少日志输出
      if (this._dragFrame) {
        // console.log("this._dragFrame--", this._dragFrame);

        cancelAnimationFrame(this._dragFrame);
      }

      this._dragFrame = requestAnimationFrame(() => {
        // 阻止事件冒泡和默认行为
        if (event.stopPropagation) event.stopPropagation();
        if (event.preventDefault) event.preventDefault();

        const startBbox = this.data("startBbox");
        const startMousePos = this.data("startMousePos");
        const handleClass = this.data("handleClass");
        const currentElementId = this.data("elementId");
        const currentMousePos = getMousePosition(event);

        // 验证数据有效性
        if (!startBbox || !startMousePos || !currentMousePos) {
          return;
        }

        // 验证鼠标位置数据的有效性
        if (
          typeof startMousePos.x !== "number" ||
          typeof startMousePos.y !== "number" ||
          typeof currentMousePos.x !== "number" ||
          typeof currentMousePos.y !== "number"
        ) {
          return;
        }

        // 验证鼠标位置数据是否为 NaN
        if (
          isNaN(startMousePos.x) ||
          isNaN(startMousePos.y) ||
          isNaN(currentMousePos.x) ||
          isNaN(currentMousePos.y)
        ) {
          return;
        }

        // 计算鼠标移动的距离
        const deltaX = currentMousePos.x - startMousePos.x;
        const deltaY = currentMousePos.y - startMousePos.y;

        // 验证增量值的有效性
        if (isNaN(deltaX) || isNaN(deltaY)) {
          return;
        }

        // 调用缩放函数
        if (currentElementId) {
          const targetElement = allElements.value.find(
            (el) => el.data("elementId") === currentElementId
          );
          if (targetElement) {
            resizeElement(targetElement, handleClass, startBbox, deltaX, deltaY);
          }
        }
      });
    });

    handle.on("dragend", function (event) {
      console.log("🎯 控制点拖拽结束:", pos.class);

      // 阻止事件冒泡和默认行为
      if (event.stopPropagation) event.stopPropagation();
      if (event.preventDefault) event.preventDefault();
      // updateRectData(element);
      const currentElementId = this.data("elementId");
      if (currentElementId) {
        const targetElement = allElements.value.find(
          (el) => el.data("elementId") === currentElementId
        );
        if (targetElement) {
          updateRectData(element);
        }
      }
      dragging.value = false;
    });

    // 为控制点添加特殊标识，防止被误选
    handle.addClass("resize-handle");
    handle.data("isResizeHandle", true);

    handles.push(handle);
  });

  // 安全地存储控制点信息，避免循环引用
  // 只存储必要的信息，不存储SVG.js对象
  element.data("resizeHandlesCount", handles.length);
  element.data("bbox", {
    x: bbox.x,
    y: bbox.y,
    width: bbox.width,
    height: bbox.height,
  });

  // 为每个控制点添加唯一标识，方便后续查找
  handles.forEach((handle, index) => {
    // 使用SVG.js的attr方法设置属性
    handle.attr("data-handle-index", index);
    handle.attr("data-element-id", element.data("elementId"));
  });

  // 将控制点存储到全局管理器中，避免循环引用
  if (!window.resizeHandlesManager) {
    window.resizeHandlesManager = new Map();
  }
  window.resizeHandlesManager.set(element.data("elementId"), handles);
};

/**
 * 调整元素大小
 * @param {Object} element - SVG元素对象
 * @param {string} handleClass - 控制点类型
 * @param {Object} startBbox - 开始时的边界框
 * @param {number} deltaX - X方向变化量
 * @param {number} deltaY - Y方向变化量
 */
const resizeElement = (element, handleClass, startBbox, deltaX, deltaY) => {
  // 验证输入数据的有效性
  if (
    !startBbox ||
    typeof startBbox.x !== "number" ||
    typeof startBbox.y !== "number" ||
    typeof startBbox.width !== "number" ||
    typeof startBbox.height !== "number"
  ) {
    return;
  }

  if (typeof deltaX !== "number" || typeof deltaY !== "number") {
    return;
  }

  // 验证起始边界框的有效性
  if (startBbox.width <= 0 || startBbox.height <= 0) {
    return;
  }

  const type = element.type;
  let newBbox = { ...startBbox };

  // 根据控制点类型计算新的边界框
  switch (handleClass) {
    case "nw": // 西北角 - 左上角拖拽
      newBbox.x = startBbox.x + deltaX;
      newBbox.y = startBbox.y + deltaY;
      newBbox.width = startBbox.width - deltaX;
      newBbox.height = startBbox.height - deltaY;
      break;
    case "ne": // 东北角 - 右上角拖拽
      newBbox.x = startBbox.x; // x不变
      newBbox.y = startBbox.y + deltaY;
      newBbox.width = startBbox.width + deltaX;
      newBbox.height = startBbox.height - deltaY;
      break;
    case "sw": // 西南角 - 左下角拖拽
      newBbox.x = startBbox.x + deltaX;
      newBbox.y = startBbox.y; // y不变
      newBbox.width = startBbox.width - deltaX;
      newBbox.height = startBbox.height + deltaY;
      break;
    case "se": // 东南角 - 右下角拖拽
      newBbox.x = startBbox.x; // x不变
      newBbox.y = startBbox.y; // y不变
      newBbox.width = startBbox.width + deltaX;
      newBbox.height = startBbox.height + deltaY;
      break;
    case "n": // 北边 - 上边拖拽
      newBbox.x = startBbox.x; // x不变
      newBbox.y = startBbox.y + deltaY;
      newBbox.width = startBbox.width; // 宽度不变
      newBbox.height = startBbox.height - deltaY;
      break;
    case "s": // 南边 - 下边拖拽
      newBbox.x = startBbox.x; // x不变
      newBbox.y = startBbox.y; // y不变
      newBbox.width = startBbox.width; // 宽度不变
      newBbox.height = startBbox.height + deltaY;
      break;
    case "e": // 东边 - 右边拖拽
      newBbox.x = startBbox.x; // x不变
      newBbox.y = startBbox.y; // y不变
      newBbox.width = startBbox.width + deltaX;
      newBbox.height = startBbox.height; // 高度不变
      break;
    case "w": // 西边 - 左边拖拽
      newBbox.x = startBbox.x + deltaX;
      newBbox.y = startBbox.y; // y不变
      newBbox.width = startBbox.width - deltaX;
      newBbox.height = startBbox.height; // 高度不变
      break;
    default:
      return;
  }

  // 验证计算结果的有效性
  if (
    isNaN(newBbox.x) ||
    isNaN(newBbox.y) ||
    isNaN(newBbox.width) ||
    isNaN(newBbox.height)
  ) {
    return;
  }

  // 确保最小尺寸和位置约束
  if (newBbox.width < minRectSize) {
    if (handleClass === "nw" || handleClass === "sw") {
      newBbox.x = startBbox.x + startBbox.width - minRectSize;
    }
    newBbox.width = minRectSize;
  }
  if (newBbox.height < minRectSize) {
    if (handleClass === "nw" || handleClass === "ne") {
      newBbox.y = startBbox.y + startBbox.height - minRectSize;
    }
    newBbox.height = minRectSize;
  }

  // 确保最小尺寸
  newBbox.width = Math.max(minRectSize, newBbox.width);
  newBbox.height = Math.max(minRectSize, newBbox.height);

  // 更新元素属性
  if (type === "rect") {
    // 更新元素属性
    element.attr({
      x: newBbox.x,
      y: newBbox.y,
      width: newBbox.width,
      height: newBbox.height,
      position: [
        newBbox.x,
        newBbox.y,
        newBbox.x + newBbox.width,
        newBbox.y,
        newBbox.x + newBbox.width,
        newBbox.y + newBbox.height,
        newBbox.x,
        newBbox.y + newBbox.height,
      ],
    });

    // 使用通用函数更新数据
    // updateRectData(element);
  }

  // 立即更新控制点位置，确保同步
  try {
    // 重新计算实际的边界框（基于更新后的元素属性）
    let actualBbox = newBbox;
    if (type === "rect") {
      actualBbox = {
        x: element.x(),
        y: element.y(),
        width: element.width(),
        height: element.height(),
      };
    } else if (type === "ellipse") {
      const cx = element.cx();
      const cy = element.cy();
      const rx = element.rx();
      const ry = element.ry();
      actualBbox = {
        x: cx - rx,
        y: cy - ry,
        width: rx * 2,
        height: ry * 2,
      };
    }

    // 立即更新控制点位置
    updateResizeHandles(element, actualBbox);

    // 同时更新元素的边界框数据
    element.data("bbox", actualBbox);
  } catch (error) {
    console.error("❌ 更新控制点位置时出错:", error);
  }
};

/**
 * 更新调整大小控制点的位置
 * @param {Object} element - SVG元素对象
 * @param {Object} bbox - 新的边界框
 */
const updateResizeHandles = (element, bbox) => {
  // 从全局管理器获取控制点
  const handles = window.resizeHandlesManager?.get(element.data("elementId"));
  // console.log("有handles", handles);

  if (!handles || handles.length === 0) return;

  const handleSize = 6; // 增加缩放点大小，提高交互体验

  // 确保边界框数据有效
  if (
    !bbox ||
    typeof bbox.x !== "number" ||
    typeof bbox.y !== "number" ||
    typeof bbox.width !== "number" ||
    typeof bbox.height !== "number"
  ) {
    console.warn("无效的边界框数据:", bbox);
    return;
  }

  // 更新角落控制点
  const corners = [
    { x: bbox.x, y: bbox.y, class: "nw" },
    { x: bbox.x + bbox.width, y: bbox.y, class: "ne" },
    { x: bbox.x, y: bbox.y + bbox.height, class: "sw" },
    { x: bbox.x + bbox.width, y: bbox.y + bbox.height, class: "se" },
  ];

  // 更新边缘控制点
  const edges = [
    { x: bbox.x + bbox.width / 2, y: bbox.y, class: "n" },
    { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height, class: "s" },
    { x: bbox.x + bbox.width, y: bbox.y + bbox.height / 2, class: "e" },
    { x: bbox.x, y: bbox.y + bbox.height / 2, class: "w" },
  ];

  [...corners, ...edges].forEach((pos, index) => {
    if (handles[index]) {
      try {
        // 确保位置数据有效
        if (typeof pos.x === "number" && typeof pos.y === "number") {
          // 使用SVG.js的attr方法设置位置
          // handles[index].attr({
          //   x: pos.x - handleSize / 2,
          //   y: pos.y - handleSize / 2,
          // });
          handles[index].attr({
            cx: pos.x, // 使用 cx 表示圆心 x 坐标
            cy: pos.y, // 使用 cy 表示圆心 y 坐标
          });
          // console.log("更新了");
        }
      } catch (error) {
        console.warn("更新控制点位置时出错:", error);
      }
    }
  });
};

/**
 * 实时更新控制点位置，跟随元素移动
 * @param {Object} element - SVG元素对象
 */
const updateResizeHandlesPosition = (element) => {
  // 快速检查
  if (!element || !element.data("resizeHandlesCount")) return;

  const type = element.type;
  let bbox;

  // 获取元素的当前边界框（只处理矩形，简化逻辑）
  if (type === "rect") {
    bbox = {
      x: element.x(),
      y: element.y(),
      width: element.width(),
      height: element.height(),
    };
  } else {
    return; // 暂时只处理矩形
  }

  if (!bbox) return;
  // console.log("我要更新控制点位置");

  // 更新控制点位置
  updateResizeHandles(element, bbox);

  // 缓存边界框数据
  element.data("bbox", bbox);
};

/**
 * 隐藏元素的所有调整大小控制点
 * @param {Object} element - SVG元素对象
 */
const hideResizeHandles = (element) => {
  // 从全局管理器获取控制点
  const handles = window.resizeHandlesManager?.get(element.data("elementId"));
  if (!handles) return;
  console.log("删除控制点handles", handles);

  // 强制移除所有控制点
  handles.forEach((handle) => {
    try {
      // 先移除拖拽功能
      if (handle.draggable) {
        handle.draggable(false);
      }
      // 再移除元素
      if (handle.remove) {
        handle.remove();
      }
    } catch (error) {
      console.warn("移除控制点时出错:", error);
    }
  });

  // 从全局管理器中移除
  window.resizeHandlesManager.delete(element.data("elementId"));

  // 清除数据引用
  element.data("resizeHandlesCount", null);
  element.data("bbox", null);
};

/**
 * 清理所有残留的控制点（全局清理）
 */
const cleanupAllResizeHandles = () => {
  // 清理全局管理器中的所有控制点
  if (window.resizeHandlesManager) {
    window.resizeHandlesManager.forEach((handles, elementId) => {
      handles.forEach((handle) => {
        try {
          if (handle.draggable) {
            handle.draggable(false);
          }
          if (handle.remove) {
            handle.remove();
          }
        } catch (error) {
          console.warn("清理控制点时出错:", error);
        }
      });
    });
    window.resizeHandlesManager.clear();
  }

  // 清理所有元素的数据
  allElements.value.forEach((element) => {
    element.data("resizeHandlesCount", null);
    element.data("bbox", null);
  });

  // console.log('✅ 已清理所有控制点')
};

/**
 * 删除选中的矩形
 */
const deleteSelectedRectangle = () => {
  if (operationType.value === "batchSelect") {
    // 批量操作
    if (!batchOperationRectList.value?.size) {
      console.log("⚠️ 没有选中的矩形，无法删除");
      return;
    } else {
      updateBatchRectData(batchOperationRectList.value, true);
      batchOperationRectList.value.forEach((ele, eleId) => {
        const rectElement = allElements.value.find(
          (item) => item.data("elementId") === eleId
        );
        if (rectElement) {
          rectElement.remove();
        }
        allElements.value = allElements.value.filter(
          (item) => item.data("elementId") !== eleId
        );
      });
      // 防止删除时有选中的矩形控制点存在
      const hoveredElementId =
        hoveredElement.value && hoveredElement.value.data("elementId");
      const selectedElementId =
        selectedElement.value && selectedElement.value.data("elementId");
      if (batchOperationRectKeyList.value.includes(hoveredElementId)) {
        // 选中矩形清除
        hoveredElement.value = null;

        // 隐藏所有控制点
        cleanupAllResizeHandles();
      }
      if (batchOperationRectKeyList.value.includes(selectedElementId)) {
        // 清除选择状态
        selectedElement.value = null;
        cleanupAllResizeHandles();
      }
      batchOperationRectList.value.clear();
      console.log("rectList.value==", rectList.value);
    }
  } else {
    if (!selectedElement.value || selectedElement.value.type !== "rect") {
      console.log("⚠️ 没有选中的矩形，无法删除");
      return;
    }
    try {
      const rectElement = selectedElement.value;
      console.log("rectElement---", rectElement);

      // 删除序号文字
      const elementId = rectElement.data("elementId");
      console.log("elementId---", elementId);

      // 从元素列表中移除矩形和文字
      const rectIndex = allElements.value.indexOf(rectElement);
      if (rectIndex > -1) {
        allElements.value.splice(rectIndex, 1);
      }
      console.log("allElements--", allElements);
      // rectList.value = rectList.value.filter((item) => item.id !== elementId);

      updateRectData(rectElement, true);

      // 删除矩形元素
      rectElement.remove();

      // 选中矩形清除
      hoveredElement.value = null;

      // 清除选择状态
      selectedElement.value = null;

      // 隐藏所有控制点
      cleanupAllResizeHandles();

      console.log("✅ 已删除选中的矩形");
    } catch (error) {
      console.error("❌ 删除矩形失败:", error);
    }
  }
};

// 删除指定的元素
const removeElement = (elementId) => {
  console.log("删除elementId---", elementId);
  const element = allElements.value.find((item) => item.data("elementId") === elementId);
  if (element) {
    if (operationType.value === "batchSelect") {
      // batchOperationRectList.value.delete(elementId)
      if (batchOperationRectList.value.has(elementId)) {
        batchOperationRectList.value.delete(elementId);
      }
    }
    if (hoveredElement.value.data("elementId") === elementId) {
      hoveredElement.value = null;
      cleanupAllResizeHandles();
    }
    if (selectedElement.value.data("elementId") === elementId) {
      selectedElement.value = null;
      cleanupAllResizeHandles();
    }

    allElements.value = allElements.value.filter(
      (item) => item.data("elementId") !== elementId
    );
    updateRectData(element, true);
    element.remove();
  }
};

/**
 * 启动绘制模式鼠标样式监控
 */
const startDrawingModeCursorMonitor = () => {
  // 清除之前的监控器
  if (window._cursorMonitorInterval) {
    clearInterval(window._cursorMonitorInterval);
  }

  // 创建新的监控器，每200ms检查一次鼠标样式（降低频率）
  window._cursorMonitorInterval = setInterval(() => {
    if (drawingMode.value && !dragging.value) {
      // 只在非拖拽状态下检查鼠标样式，避免拖拽时的重复设置
      checkAndSetDrawingCursor();
    }
  }, 200);

  console.log("✅ 绘制模式鼠标样式监控已启动");
};

/**
 * 强制设置绘制模式鼠标样式（完整版本，用于关键时机）
 */
const forceDrawingModeCursor = () => {
  if (!drawingMode.value) return;

  try {
    // 使用多种方式强制设置鼠标样式
    if (svgCanvas.value) {
      svgCanvas.value.style.cursor = "crosshair";
      svgCanvas.value.style.setProperty("cursor", "crosshair", "important");
    }

    // 设置body的鼠标样式
    document.body.style.cursor = "crosshair";
    document.body.style.setProperty("cursor", "crosshair", "important");

    // 设置html的鼠标样式
    document.documentElement.style.cursor = "crosshair";
    document.documentElement.style.setProperty("cursor", "crosshair", "important");

    // 强制覆盖所有可能的鼠标样式
    const style = document.createElement("style");
    style.id = "force-drawing-cursor";
    style.textContent = `
      * {
        cursor: crosshair !important;
      }
    `;

    // 移除旧的样式
    const oldStyle = document.getElementById("force-drawing-cursor");
    if (oldStyle) {
      oldStyle.remove();
    }

    // 添加新样式
    document.head.appendChild(style);

    console.log("✅ 强制设置绘制模式鼠标样式");
  } catch (error) {
    console.error("❌ 强制设置鼠标样式失败:", error);
  }
};

/**
 * 轻量级鼠标样式检查和设置（用于定时监控）
 */
const checkAndSetDrawingCursor = () => {
  if (!drawingMode.value) return;

  try {
    // 只在必要时设置鼠标样式，避免重复操作
    let needsUpdate = false;

    // 检查画布鼠标样式
    if (svgCanvas.value && svgCanvas.value.style.cursor !== "crosshair") {
      svgCanvas.value.style.cursor = "crosshair";
      needsUpdate = true;
    }

    // 检查body鼠标样式
    if (document.body.style.cursor !== "crosshair") {
      document.body.style.cursor = "crosshair";
      needsUpdate = true;
    }

    // 只在需要更新时记录日志
    if (needsUpdate) {
      console.log("🔍 检测到鼠标样式被覆盖，已恢复");
    }
  } catch (error) {
    console.error("❌ 检查鼠标样式失败:", error);
  }
};

/**
 * 恢复默认鼠标样式
 */
const restoreNormalCursor = () => {
  try {
    // 移除强制绘制的鼠标样式
    const forceStyle = document.getElementById("force-drawing-cursor");
    if (forceStyle) {
      forceStyle.remove();
    }

    // 恢复默认鼠标样式
    if (svgCanvas.value) {
      svgCanvas.value.style.cursor = "default";
      svgCanvas.value.style.removeProperty("cursor");
    }

    document.body.style.cursor = "default";
    document.body.style.removeProperty("cursor");

    document.documentElement.style.cursor = "default";
    document.documentElement.style.removeProperty("cursor");

    // console.log("✅ 已恢复默认鼠标样式");
  } catch (error) {
    console.error("❌ 恢复默认鼠标样式失败:", error);
  }
};

/**
 * 重新激活绘制模式
 */
const reactivateDrawingMode = () => {
  if (!drawingMode.value || !svgCanvas.value) return;

  try {
    console.log("🔄 重新激活绘制模式...");

    // 重新设置绘制模式状态
    drawing.value = false;
    currentElement.value = null;
    startPoint.value = null;

    // 重新添加点击事件监听器
    if (window._rectClickHandler) {
      svgCanvas.value.removeEventListener("click", window._rectClickHandler, {
        capture: true,
      });
    }

    // 重新创建点击事件处理器
    window._rectClickHandler = (event) => {
      console.log("🎯 重新激活的矩形绘制点击事件被触发", {
        target: event.target,
        currentTarget: event.currentTarget,
        drawingMode: drawingMode.value,
        viewport: {
          scale: viewport.value.scale,
          translateX: viewport.value.translateX,
          translateY: viewport.value.translateY,
        },
      });

      // 添加事件ID，防止重复处理
      if (event._rectClickProcessed) {
        console.log("🚫 事件已被处理，跳过重复处理");
        return;
      }
      event._rectClickProcessed = true;

      // 在绘制模式下，阻止事件冒泡，防止触发其他选择逻辑
      event.stopPropagation();
      event.preventDefault();

      handleRectClick(event);
    };

    // 重新添加点击事件监听器
    svgCanvas.value.addEventListener("click", window._rectClickHandler, {
      capture: true,
    });

    // 强制设置鼠标样式
    forceDrawingModeCursor();
  } catch (error) {
    console.error("❌ 重新激活绘制模式失败:", error);
  }
};

/**
 * 显示元素的所有调整大小控制点
 * @param {Object} element - SVG元素对象
 */
const showResizeHandles = (element) => {
  // 安全检查：确保元素存在且有效
  if (!element) {
    console.warn("⚠️ showResizeHandles: element 为 null 或 undefined");
    return;
  }

  // 检查元素的 node 属性是否存在
  if (!element.node) {
    console.warn("⚠️ showResizeHandles: element.node 为 null，元素可能已被删除");
    return;
  }

  // 检查元素是否仍然在DOM中
  if (!document.contains(element.node)) {
    console.warn("⚠️ showResizeHandles: 元素已不在DOM中");
    return;
  }

  // 确保元素有类型属性
  if (!element.type) {
    console.warn("元素缺少类型属性，无法显示控制点");
    return;
  }

  // 重要：在显示新控制点之前，先隐藏所有其他元素的控制点
  // 确保只有当前激活的元素显示控制点
  allElements.value.forEach((el) => {
    if (el && el !== element && el.data("resizeHandlesCount")) {
      hideResizeHandles(el);
    }
  });

  // 检查是否已经有控制点
  if (element.data("resizeHandlesCount")) {
    console.log("元素已有控制点，跳过创建");
    return;
  }

  // 添加控制点
  addResizeHandles(element);

  // 确保控制点在最上层
  const handles = window.resizeHandlesManager?.get(element.data("elementId"));
  if (handles) {
    handles.forEach((handle) => {
      if (handle && handle.front) {
        handle.front();
      }
    });
  }
};

// ==================== 形状绘制功能 ====================

/**
 * 选择要绘制的形状类型
 * @param {string} shape - 形状类型：'rect', 'ellipse', 'polygon'
 */
const selectShape = (shape) => {
  currentShape.value = shape;
  drawingMode.value = true; // 进入绘制模式

  clearSelection(); // 切换形状时清除选择

  // 如果选择矩形，进入点击绘制模式
  if (shape === "rect") {
    console.log("🎯 进入矩形绘制模式");
    enterRectDrawingMode();
  }
};

/**
 * 移除绘制模式的事件阻止器
 */
const removeDrawingEventBlocker = () => {
  if (!svgCanvas.value) return;

  console.log("🔓 绘制完成后恢复所有元素的拖拽功能");

  // 恢复所有元素的拖拽功能
  allElements.value.forEach((el) => {
    if (el && el.draggable === false) {
      // 检查是否有原始拖拽状态记录
      const originalDraggable = el.data("originalDraggable");
      if (originalDraggable !== undefined) {
        el.draggable(originalDraggable);
        el.data("originalDraggable", null); // 清理记录
        console.log("🔓 恢复元素拖拽:", el.type, "原始状态:", originalDraggable);
      } else {
        el.draggable(true);
        console.log("🔓 恢复元素拖拽:", el.type);
      }
    }
  });
};

/**
 * 在绘制模式下，临时禁用所有现有矩形的拖拽功能
 */
const changeRectanglesDragStatus = (status = false) => {
  console.log("🔒 绘制模式下，临时禁用所有现有矩形的拖拽功能");

  allElements.value.forEach((el) => {
    // if (el && el.type === "rect" && el.draggable !== false) {
    if (el && el.type === "rect") {
      // 记录原始拖拽状态
      el.data("originalDraggable", el.draggable);
      el.draggable(status);
      console.log("🔒 禁用矩形拖拽:", el.type);
    }
  });
};

/**
 * 进入矩形点击绘制模式
 */
const enterRectDrawingMode = () => {
  // 设置绘制状态
  drawing.value = false; // 还未开始绘制
  currentElement.value = null;
  startPoint.value = null;

  // 在绘制模式下，临时禁用所有现有矩形的拖拽功能

  changeRectanglesDragStatus();

  // 设置绘制模式下的鼠标样式为 + 号
  forceDrawingModeCursor();

  // 添加点击事件监听器
  if (svgCanvas.value) {
    // 先清理所有可能存在的矩形绘制事件监听器
    cleanupRectDrawingListeners();

    // 创建新的点击事件处理器
    window._rectClickHandler = (event) => {
      // 添加事件ID，防止重复处理
      if (event._rectClickProcessed) {
        console.log("🚫 事件已被处理，跳过重复处理");
        return;
      }
      event._rectClickProcessed = true;

      // 在绘制模式下，阻止事件冒泡，防止触发其他选择逻辑
      event.stopPropagation();
      event.preventDefault();

      handleRectClick(event);
    };

    // 使用 capture: true，确保绘制事件在捕获阶段就被处理，优先级最高
    svgCanvas.value.addEventListener("click", window._rectClickHandler, {
      capture: true,
    });

    console.log("✅ 矩形点击绘制模式已启用");

    // 启动绘制模式鼠标样式监控
    startDrawingModeCursorMonitor();
  }
};

/**
 * 处理矩形点击绘制
 * @param {MouseEvent} event - 点击事件
 */
const handleRectClick = (event) => {
  // 防重复调用机制：如果正在处理点击事件，直接返回
  if (window._isProcessingClick) {
    console.log("🚫 正在处理点击事件，跳过重复调用");
    return;
  }

  // 设置处理标志
  window._isProcessingClick = true;

  // 添加调用栈跟踪，帮助调试重复点击问题
  console.log("🔍 handleRectClick 调用栈:", new Error().stack);

  if (!drawingMode.value) {
    console.log("❌ 不在绘制模式");
    window._isProcessingClick = false; // 重置标志
    return;
  }

  if (currentShape.value !== "rect") {
    console.log("❌ 不是矩形绘制模式");
    window._isProcessingClick = false; // 重置标志
    return;
  }

  const pos = getMousePosition(event);

  if (!startPoint.value) {
    // 第一次点击：设置起始点
    startPoint.value = pos;
    console.log("🎯 设置起始点:", pos);
    console.log("🔍 设置startPoint后立即检查:", {
      startPoint: startPoint.value,
      drawing: drawing.value,
      currentElement: !!currentElement.value,
    });

    // 创建预览矩形
    currentElement.value = svgDoc.value
      .rect(0, 0)
      .attr({
        x: pos.x,
        y: pos.y,
        fill: hexToRgb(selectSettingMsg.value.fill),
        stroke: selectSettingMsg.value.fill,
        strokeWidth: 2,
      })
      .style("cursor", "move");

    // 开始绘制状态
    drawing.value = true;

    // 每次绘制都重新设置鼠标移动事件监听器
    if (svgCanvas.value) {
      // 先移除旧的鼠标移动事件监听器（如果存在）
      if (window._rectMoveHandler) {
        svgCanvas.value.removeEventListener("mousemove", window._rectMoveHandler);
      }

      // 创建新的鼠标移动事件监听器
      window._rectMoveHandler = (moveEvent) => {
        if (drawing.value && currentElement.value && startPoint.value) {
          updateRectDrawingClick(getMousePosition(moveEvent));
        }
      };
      svgCanvas.value.addEventListener("mousemove", window._rectMoveHandler);
      console.log("✅ 开始实时预览");
    }
  } else {
    // 更新矩形尺寸
    updateRectDrawingClick(pos);

    // 完成绘制
    finishRectDrawing();
  }

  // 清除处理标志
  window._isProcessingClick = false;
};

/**
 * 更新矩形绘制（鼠标移动时）
 * @param {{x: number, y: number}} pos - 当前鼠标位置
 */
const updateRectDrawingClick = (pos) => {
  if (!currentElement.value || !startPoint.value) return;

  const width = pos.x - startPoint.value.x;
  const height = pos.y - startPoint.value.y;

  // 确保最小尺寸，避免绘制出0尺寸的矩形
  //   const minSize = minRectSize;
  const finalWidth = Math.abs(width) < minRectSize ? minRectSize : Math.abs(width);
  const finalHeight = Math.abs(height) < minRectSize ? minRectSize : Math.abs(height);

  // 处理负值尺寸（从任意方向拖拽）
  if (width < 0) {
    currentElement.value.attr({ x: pos.x, width: finalWidth });
  } else {
    currentElement.value.attr({ x: startPoint.value.x, width: finalWidth });
  }

  if (height < 0) {
    currentElement.value.attr({ y: pos.y, height: finalHeight });
  } else {
    currentElement.value.attr({ y: startPoint.value.y, height: finalHeight });
  }
};
// 增加矩形列表数据
function addRectList(element, rectData = {}) {
  saveHistory();
  // 获取矩形属性
  const elementId = element.data("elementId");
  const x = element.x();
  const y = element.y();
  const width = element.width();
  const height = element.height();

  // 计算position数组 [x1,y1,x2,y2,x3,y3,x4,y4]
  const position = [
    x,
    y, // 左上角
    x + width,
    y, // 右上角
    x + width,
    y + height, // 右下角
    x,
    y + height, // 左下角
  ];

  // 添加到矩形数据列表
  rectList.value.push({
    id: elementId,
    rectType: rectType.value || element.data("rectType"),
    x,
    y,
    width,
    height,
    fieldName: "",
    desc: "",
    formatType: "",
    position,
    ...rectData,
  });
  console.log("rectList.value==", rectList.value);
}

function saveHistory() {
  console.log("保存历史", rectList.value);

  historyOperationList.undoStack.push(deepClone(rectList.value));
  // 超过 10 步就删除最早的一步
  if (historyOperationList.undoStack.length > props.maxHistory) {
    historyOperationList.undoStack.shift();
  }
  // 新操作发生时，清空 redoStack
  historyOperationList.redoStack = [];
}

// 更新矩形的数据源
const updateRectData = (elementOrId, isDelete = false, isBatch = false) => {
  if (!elementOrId) return;
  if (!isBatch) {
    saveHistory();
  }
  const elementId =
    typeof elementOrId?.data === "function" && elementOrId?.data("elementId")
      ? elementOrId?.data("elementId")
      : elementOrId;
  console.log("elementId", elementId);
  const element = allElements.value.find((item) => {
    return item.data("elementId") === elementId;
  });

  if (!isDelete) {
    const index = rectList.value.findIndex((item) => item.id === elementId);

    if (index !== -1) {
      const newRectList = [...rectList.value];
      newRectList[index] = {
        ...newRectList[index],
        x: element.x(),
        y: element.y(),
        width: element.width(),
        height: element.height(),
        position: [
          element.x(),
          element.y(),
          element.x() + element.width(),
          element.y(),
          element.x() + element.width(),
          element.y() + element.height(),
          element.x(),
          element.y() + element.height(),
        ],
      };
      rectList.value = newRectList; // 整体赋值，触发 set 方法
      console.log("Updated rectList data for element:", elementId);
    }
  } else {
    console.log("删除矩形elementId", elementId);
    console.log("删除矩形rectList.value", rectList.value);

    rectList.value = rectList.value.filter((item) => item.id !== elementId);
  }
};

const updateBatchRectData = (elementList, isDelete = false) => {
  saveHistory();
  if (!isDelete) {
    elementList.forEach((element, elementId) => {
      updateRectData(elementId, false, true);
    });
  } else {
    const keyList = [];
    elementList.forEach((_, key) => {
      keyList.push(key);
    });

    rectList.value = rectList.value.filter((item) => {
      return !keyList.includes(item.id);
    });
    console.log("删除矩形rectList.value", rectList.value);
  }
};

/**
 * 完成矩形绘制
 */
const finishRectDrawing = () => {
  if (!currentElement.value) return;

  // 设置元素类型和ID
  currentElement.value.type = "rect";
  const eleId = uuidv4();
  currentElement.value.data("elementId", eleId);

  // 添加到元素列表
  allElements.value.push(currentElement.value);
  console.log("allElements.value--", allElements.value);

  // 绘制完成保证所有矩形的拖动功能
  allElements.value.forEach((el) => {
    if (el && el.type === "rect") {
      el.draggable(true);
      console.log("🔒 禁用矩形拖拽:", el.type);
    }
  });

  // 为新元素添加拖拽事件监听器，确保拖拽时能正确激活
  // 使用闭包捕获元素引用，避免currentElement.value被清空后的问题
  const element = currentElement.value;
  // 创建矩形时更新标注json数据
  addRectList(element);

  element.off("dragstart dragmove dragend");
  element.on("dragstart", () => {
    console.log("🎯 新绘制矩形开始拖拽");
    // 拖拽开始时，确保这个元素被选中
    if (selectedElement.value !== element) {
      // 临时允许选择
      const tempDrawingMode = drawingMode.value;
      drawingMode.value = false;
      selectElement(element);
      drawingMode.value = tempDrawingMode;
    }
    dragging.value = true;

    // 绘制模式下拖拽时，设置一次鼠标样式即可（拖拽过程中不需要重复设置）
    if (drawingMode.value) {
      if (svgCanvas.value) {
        svgCanvas.value.style.cursor = "crosshair";
      }
      document.body.style.cursor = "crosshair";
    }

    // 重要：拖拽开始时，记录绘制模式状态
    if (!window.dragStateMap) {
      window.dragStateMap = new Map();
    }
    const elementId =
      element.data("elementId") ||
      `drag_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    element.data("dragStateId", elementId);
    window.dragStateMap.set(elementId, { wasInDrawingMode: drawingMode.value });
  });

  element.on("dragmove", () => {
    // 拖拽过程中，更新控制点位置
    if (selectedElement.value === element) {
      updateResizeHandlesPosition(element);
    }
  });

  element.on("dragend", () => {
    console.log("🎯 新绘制矩形拖拽结束");
    dragging.value = false;
    // 调用公共函数限制矩形在 SVG 区域内
    if (svgCanvas.value && element) {
      limitRectToSVG(element, svgCanvas.value);
    }
    // 拖拽结束后，更新控制点位置
    updateResizeHandlesPosition(element);
    console.log({
      x: element.x(),
      y: element.y(),
      width: element.width(),
      height: element.height(),
    });

    // 使用通用函数更新矩形数据
    updateRectData(element);

    // 如果拖拽前在绘制模式，但拖拽后绘制模式被意外关闭，则恢复
    const dragStateId = element.data("dragStateId");
    if (dragStateId) {
      const dragState = window.dragStateMap?.get(dragStateId);
      if (dragState?.wasInDrawingMode) {
        console.log("🔄 检测到拖拽前在绘制模式，现在确保绘制模式状态正确");

        // 如果绘制模式被意外关闭，则恢复
        if (!drawingMode.value) {
          drawingMode.value = true;
          console.log("✅ 已恢复绘制模式状态");
        }

        // 清理状态记录
        window.dragStateMap.delete(dragStateId);
        element.data("dragStateId", null);
      }
    }

    // 如果当前在绘制模式，确保鼠标样式正确
    if (drawingMode.value) {
      if (svgCanvas.value) {
        svgCanvas.value.style.cursor = "crosshair";
      }
      document.body.style.cursor = "crosshair";
      console.log("✅ 拖拽结束后恢复绘制模式鼠标样式");
    }

    // 重要：拖拽结束后，确保绘制功能正常工作
    // 检查事件监听器是否还存在
    if (drawingMode.value && svgCanvas.value) {
      console.log("🔄 拖拽后重新激活绘制模式");

      // 重新启动绘制模式的完整流程
      // 1. 重置绘制状态
      startPoint.value = null;
      drawing.value = false;
      currentElement.value = null;

      // 2. 重新设置鼠标样式
      forceDrawingModeCursor();

      // 3. 重新启动鼠标样式监控
      startDrawingModeCursorMonitor();

      // 4. 重新创建并添加点击事件监听器
      if (window._rectClickHandler) {
        // 先移除旧的监听器
        svgCanvas.value.removeEventListener("click", window._rectClickHandler, {
          capture: true,
        });
      }

      // 重新创建点击事件处理器
      window._rectClickHandler = (event) => {
        // 添加事件ID，防止重复处理
        if (event._rectClickProcessed) {
          console.log("🚫 事件已被处理，跳过重复处理");
          return;
        }
        event._rectClickProcessed = true;

        // 在绘制模式下，阻止事件冒泡，防止触发其他选择逻辑
        event.stopPropagation();
        event.preventDefault();

        handleRectClick(event);
      };

      // 重新添加点击事件监听器
      svgCanvas.value.addEventListener("click", window._rectClickHandler, {
        capture: true,
      });
      console.log("✅ 拖拽后已重新激活绘制模式，状态已重置");
    }
  });

  // 重要：在视口变换后，确保新绘制的矩形位置正确
  // 检查是否需要调整矩形位置以适应视口变换
  if (
    viewport.value.scale !== 1 ||
    viewport.value.translateX !== 0 ||
    viewport.value.translateY !== 0
  ) {
    // 获取矩形的当前属性
    const currentX = currentElement.value.x();
    const currentY = currentElement.value.y();
    const currentWidth = currentElement.value.width();
    const currentHeight = currentElement.value.height();

    // 验证位置是否正确（在视口变换后，位置应该已经是正确的）
    const expectedX = startPoint.value.x;
    const expectedY = startPoint.value.y;

    if (Math.abs(currentX - expectedX) > 1 || Math.abs(currentY - expectedY) > 1) {
      console.warn("⚠️ 矩形位置可能不正确，尝试修正");
      currentElement.value.attr({
        x: expectedX,
        y: expectedY,
        width: currentWidth,
        height: currentHeight,
      });
    }
  }

  // 显示缩放点
  // showResizeHandles(currentElement.value);

  // 选中新绘制的元素（绘制完成后，可以安全选择）
  // 注意：这里需要临时允许选择，因为绘制已经完成
  const tempDrawingMode = drawingMode.value;
  drawingMode.value = false; // 临时禁用绘制模式，允许选择

  selectElement(currentElement.value);

  // 恢复绘制模式状态
  drawingMode.value = tempDrawingMode;

  // 清理绘制状态
  drawing.value = false;
  currentElement.value = null;
  startPoint.value = null;

  // 退出绘制模式，恢复正常的交互功能
  // 每次绘制完成后都需要重新按N键进入绘制模式
  drawingMode.value = false;

  // 清理事件监听器
  cleanupRectDrawingListeners();

  // 恢复默认鼠标样式
  restoreNormalCursor();

  // 停止绘制模式鼠标样式监控
  if (window._cursorMonitorInterval) {
    clearInterval(window._cursorMonitorInterval);
    window._cursorMonitorInterval = null;
    console.log("✅ 绘制模式鼠标样式监控已停止");
  }

  // 确保所有元素都有拖拽功能
  allElements.value.forEach((el) => {
    if (el && el.node && document.contains(el.node)) {
      try {
        if (!el.draggable) {
          el.draggable(true);
        }
        // 检查拖拽功能是否真的被启用
        console.log(`🔍 元素拖拽状态: ${el.type}, draggable=${!!el.draggable}`);
      } catch (error) {
        console.error("❌ 启用拖拽功能失败:", error);
      }
    }
  });
};

/**
 * 清理矩形绘制的事件监听器
 */
const cleanupRectDrawingListeners = () => {
  if (svgCanvas.value) {
    if (window._rectClickHandler) {
      svgCanvas.value.removeEventListener("click", window._rectClickHandler);
      window._rectClickHandler = null;
    }
    if (window._rectMoveHandler) {
      svgCanvas.value.removeEventListener("mousemove", window._rectMoveHandler);
      window._rectMoveHandler = null;
    }
  }
};

/**
 * 更新绘制中的形状（鼠标移动时）
 * @param {{x: number, y: number}} pos - 当前鼠标位置
 */
const updateDrawingShape = (pos) => {
  if (!drawing.value || !currentElement.value) return;

  switch (currentShape.value) {
    case "rect":
      updateRectDrawing(pos);
      break;
  }
};

/**
 * 更新矩形绘制
 * @param {{x: number, y: number}} pos - 当前鼠标位置
 */
const updateRectDrawing = (pos) => {
  const width = pos.x - startPoint.value.x;
  const height = pos.y - startPoint.value.y;

  // 处理负值尺寸（从任意方向拖拽）
  if (width < 0) {
    currentElement.value.attr({ x: pos.x, width: Math.abs(width) });
  } else {
    currentElement.value.attr({ width: width });
  }

  if (height < 0) {
    currentElement.value.attr({ y: pos.y, height: Math.abs(height) });
  } else {
    currentElement.value.attr({ height: height });
  }
};

// ==================== 元素检测与选择功能 ====================

/**
 * 判断点是否在元素内
 * @param {{x: number, y: number}} pos - 要检测的点坐标
 * @param {Object} element - SVG元素对象
 * @returns {boolean} 是否在元素内
 */
const isPointInElement = (pos, element) => {
  const type = element.type;

  switch (type) {
    case "rect":
      return isPointInRect(pos, element);
    default:
      return false;
  }
};

/**
 * 检测点是否在矩形内
 * @param {{x: number, y: number}} pos - 点坐标
 * @param {Object} element - 矩形元素
 * @returns {boolean} 是否在矩形内
 */
const isPointInRect = (pos, element) => {
  // console.log('pos--', pos)
  // console.log('element--', element)
  const x = element.x();
  const y = element.y();
  const width = element.width();
  const height = element.height();

  // 添加容差，让边缘区域也容易被选中
  const tolerance = 2;
  return (
    pos.x >= x - tolerance &&
    pos.x <= x + width + tolerance &&
    pos.y >= y - tolerance &&
    pos.y <= y + height + tolerance
  );
};

/**
 * 计算元素面积
 * @param {Object} element - SVG元素对象
 * @returns {number} 面积值
 */
const calculateElementArea = (element) => {
  const type = element.type;

  try {
    switch (type) {
      case "rect":
        const width = Math.max(0, element.width());
        const height = Math.max(0, element.height());
        return width * height;
      default:
        return 0;
    }
  } catch (error) {
    console.error("计算面积时出错:", error);
    return 0;
  }
};

/**
 * 在指定位置查找元素（透视层选择）
 * @param {{x: number, y: number}} pos - 查找位置
 * @returns {Object|null} 找到的元素或null
 */
const findElementAtPosition = (pos) => {
  // 性能优化：如果正在拖拽，直接返回当前选中的元素
  if (dragging.value && selectedElement.value) {
    return selectedElement.value;
  }

  // 重要：如果当前有选中的元素，检查鼠标是否在其区域内
  // 但如果有其他元素也在该位置，需要智能选择
  if (selectedElement.value && isPointInElement(pos, selectedElement.value)) {
    // 检查是否有其他元素也在该位置
    const overlappingElements = [];
    for (let i = 0; i < allElements.value.length; i++) {
      const element = allElements.value[i];

      if (isPointInElement(pos, element)) {
        overlappingElements.push({
          element: element,
          index: i,
          area: calculateElementArea(element),
          type: element.type,
        });
      }
    }

    if (window.debugMode) {
      console.log("🔍 重叠元素检测结果:", overlappingElements);
    }

    // 如果只有一个元素，直接返回当前选中的
    if (overlappingElements.length === 1) {
      return selectedElement.value;
    }

    // 如果有多个重叠元素，需要智能选择
    // 优先选择面积较小的（更精确的标注）
    if (overlappingElements.length > 1) {
      overlappingElements.sort((a, b) => a.area - b.area);
      if (window.debugMode) {
        console.log("🔍 按面积排序后的重叠元素:", overlappingElements);
        console.log("🔍 最终选择:", overlappingElements[0]);
      }
      return overlappingElements[0].element;
    }
  }

  const elementsAtPosition = [];

  // 找到所有包含该点的元素
  for (let i = 0; i < allElements.value.length; i++) {
    const element = allElements.value[i];
    if (isPointInElement(pos, element)) {
      // console.log("element--------", element);
      const area = calculateElementArea(element);
      elementsAtPosition.push({
        element: element,
        index: i,
        area: area,
        type: element.type,
      });
    }
  }

  if (elementsAtPosition.length === 0) {
    return null;
  }

  if (elementsAtPosition.length === 1) {
    return elementsAtPosition[0].element;
  }

  // 多个元素重叠时，优先选择面积最小的（最精确的标注）
  // 性能优化：减少日志输出，只在调试时显示
  if (window.debugMode) {
    console.log(`找到 ${elementsAtPosition.length} 个重叠元素，开始智能排序...`);
  }

  // 按面积排序，面积越小优先级越高
  elementsAtPosition.sort((a, b) => {
    const areaDiff = a.area - b.area;

    // 面积差异大于10时，按面积排序（增加阈值，减少频繁切换）
    if (Math.abs(areaDiff) > 10) {
      if (window.debugMode) {
        console.log(`面积差异较大，按面积排序`);
      }
      return areaDiff;
    }

    // 面积相近时，按绘制顺序排序，后绘制的优先
    if (window.debugMode) {
      console.log(`面积相近，按绘制顺序排序`);
    }
    return b.index - a.index;
  });

  const selected = elementsAtPosition[0];
  if (window.debugMode) {
    console.log(
      `最终选择: ${selected.type}, 面积=${selected.area.toFixed(2)}, 索引=${
        selected.index
      }`
    );
  }

  return selected.element;
};

// ==================== 元素选择与状态管理 ====================

/**
 * 选择元素
 * @param {Object} element - 要选择的元素
 */
const selectElement = (element) => {
  // 在绘制模式下，禁止选择元素，防止干扰绘制逻辑
  if (drawingMode.value) {
    console.log("🚫 绘制模式下，禁止选择元素，防止干扰绘制逻辑");
    return;
  }

  // 安全检查：确保传入的元素有效
  if (!element) {
    console.warn("⚠️  传入的元素为 null 或 undefined");
    return;
  }

  // 检查元素的 node 属性是否存在
  if (!element.node) {
    console.warn("⚠️  element.node 为 null，元素可能已被删除");
    return;
  }

  // 检查元素是否仍然在DOM中
  if (!document.contains(element.node)) {
    console.warn("⚠️  元素已不在DOM中");
    return;
  }

  // 在绘制模式下，不要过度清理，保持绘制功能
  if (!drawingMode.value) {
    // 先全局清理所有残留的控制点
    cleanupAllResizeHandles();
  }

  // 清除之前的选择,只有在非多选的时候
  // 需要调整的逻辑
  if (selectedElement.value && selectedElement.value !== element) {
    let needClear = false;
    if (operationType.value != "batchSelect") {
      needClear = true;
    }
    if (operationType.value == "batchSelect") {
      if (
        !batchOperationRectKeyList.value?.length ||
        !batchOperationRectKeyList.value.includes(selectedElement.value.data("elementId"))
      ) {
        needClear = true;
      }
    }
    if (needClear) {
      selectedElement.value.attr({
        strokeWidth: 2,
        fill: getDefaultFill(selectedElement.value),
        stroke: getDefaultStroke(selectedElement.value),
      });
    }
  }

  // 设置新的选择,切移入元素不包含在多选项中才设置移入样式，防止冲突
  selectedElement.value = element;

  let needSetting = false;
  if (operationType.value != "batchSelect") {
    needSetting = true;
  }
  if (operationType.value == "batchSelect") {
    if (
      !batchOperationRectKeyList.value?.length ||
      !batchOperationRectKeyList.value.includes(element.data("elementId"))
    ) {
      needSetting = true;
    }
  }
  // console.log('needSetting', needSetting)
  if (needSetting) {
    // console.log('需要更新')

    element.attr({
      stroke: getDefaultStroke(selectedElement.value),
      strokeWidth: 2,
      fill: getDefaultFill(selectedElement.value, 0.2),
    });
  }

  // 将选中的元素移到最上层
  element.front();

  // 显示缩放控制点
  showResizeHandles(element);

  // 为选中的元素添加拖拽时的控制点同步更新
  // 注意：不要覆盖新绘制矩形的拖拽事件监听器
  if (element.draggable && !element.data("hasDragHandlers")) {
    element.data("hasDragHandlers", true);

    // 添加拖拽事件监听器
    element.on("drag", () => {
      // 实时更新控制点位置，跟随元素移动
      updateResizeHandlesPosition(element);
    });
  }

  // 重要：确保选中的元素有完整的拖拽功能
  if (!element.draggable) {
    element.draggable(true);
    console.log("✅ selectElement: 为选中元素启用拖拽功能:", element.type);
  }

  // 重要：选择元素时，确保所有元素都有拖拽功能
  allElements.value.forEach((el) => {
    // 安全检查：确保元素有效
    if (!el || !el.node || !document.contains(el.node)) {
      console.warn("⚠️ selectElement: 跳过无效元素");
      return;
    }

    // 确保所有矩形都有拖拽功能
    if (el.type === "rect" && !el.draggable) {
      el.draggable(true);
      console.log("✅ selectElement: 为现有矩形启用拖拽功能:", el.type);
    }
    if (!el.draggable) {
      el.draggable();
      console.log("✅ 启用元素拖拽:", el.type);
    }
    // 清除拖拽优先级标记
    el.data("dragPriority", false);
  });
};

/**
 * 清除所有选择
 */
const clearSelection = () => {
  // 清除悬停状态
  if (hoveredElement.value) {
    try {
      hoveredElement.value.attr({
        stroke: getDefaultStroke(hoveredElement.value),
        strokeWidth: 2,
        "stroke-dasharray": "none",
        fill: getDefaultFill(hoveredElement.value),
      });
    } catch (error) {
      console.warn("⚠️ clearSelection: 清除悬停状态时出错:", error);
    }
    hoveredElement.value = null;
  }

  // 清除选中状态
  if (selectedElement.value) {
    try {
      selectedElement.value.attr({
        stroke: getDefaultStroke(selectedElement.value),
        strokeWidth: 2,
        "stroke-dasharray": "none",
        fill: getDefaultFill(selectedElement.value),
      });

      // 移除拖拽事件监听器
      if (selectedElement.value.off) {
        selectedElement.value.off("drag");
      }
    } catch (error) {
      console.warn("⚠️ clearSelection: 清除选中状态时出错:", error);
    }

    selectedElement.value = null;
  }

  // 全局清理所有控制点
  cleanupAllResizeHandles();

  // 恢复所有元素的正常拖拽状态
  restoreNormalDragState();
};

/**
 * 鼠标移动事件处理
 * @param {MouseEvent} event - 鼠标移动事件
 */
const onMouseMove = (event) => {
  // isSvgDragging.value = true
  if (isSvgMouseDown.value) {
    const dx = Math.abs(event.clientX - startX.value);
    const dy = Math.abs(event.clientY - startY.value);
    if (dx > DRAG_THRESHOLD || dy > DRAG_THRESHOLD) {
      isSvgDragging.value = true;
    }
  }
  // console.log('onMouseMove------isSvgDragging.value', isSvgDragging.value)
  const pos = getMousePosition(event);

  // 跟踪全局鼠标位置，用于快捷键检测
  window.mouseX = event.clientX;
  window.mouseY = event.clientY;

  // 处理绘制模式 - 优先级最高
  if (drawingMode.value) {
    // 绘制模式下，简单设置鼠标样式即可（避免频繁调用强制设置函数）
    if (svgCanvas.value && svgCanvas.value.style.cursor !== "crosshair") {
      svgCanvas.value.style.cursor = "crosshair";
    }
    if (document.body.style.cursor !== "crosshair") {
      document.body.style.cursor = "crosshair";
    }

    if (drawing.value && currentElement.value) {
      updateDrawingShape(pos);
      return; // 正在绘制时不处理悬停预览
    } else {
      // 绘制模式下但还未开始绘制，不处理悬停预览
      // 避免在绘制过程中意外选中其他矩形
      return;
    }
  } else {
    // 非绘制模式下，恢复默认鼠标样式
    // restoreNormalCursor();
  }

  // 处理拖拽模式下的实时选中
  if (dragging.value) {
    // handleDragSelection(pos);
    return; // 拖拽模式下不处理悬停预览
  }

  // 处理悬停预览（非绘制模式且非拖拽模式）
  if (!drawingMode.value && !drawing.value && !dragging.value) {
    handleHoverPreview(pos);
  }
};

/**
 * 处理拖拽过程中的实时选中
 * @param {{x: number, y: number}} pos - 当前鼠标位置
 */
const handleDragSelection = (pos) => {
  // 在拖拽过程中，保持当前选中元素的选中状态
  // 不因为鼠标经过其他元素而改变选择，确保拖拽的连续性
  if (selectedElement.value) {
    // 只更新当前选中元素的控制点位置
    updateResizeHandlesPosition(selectedElement.value);
  }
};

/**
 * 检查鼠标是否在缩放点附近
 * @param {{x: number, y: number}} pos - 鼠标位置
 * @param {Object} element - 元素对象
 * @returns {boolean} 是否在缩放点附近
 */
const isNearResizeHandles = (pos, element) => {
  if (!element || !element.data("resizeHandlesCount")) return false;

  const handles = window.resizeHandlesManager?.get(element.data("elementId"));
  if (!handles) return false;

  // 检查鼠标是否在任何缩放点的扩展区域内
  const extendedHandleSize = 25; // 扩展的交互区域

  for (const handle of handles) {
    if (handle && handle.attr) {
      const handleX = handle.attr("x") + handle.attr("width") / 2;
      const handleY = handle.attr("y") + handle.attr("height") / 2;

      const distance = Math.sqrt((pos.x - handleX) ** 2 + (pos.y - handleY) ** 2);

      if (distance < extendedHandleSize) {
        return true;
      }
    }
  }

  return false;
};
/**
 * 限制矩形元素在 SVG 区域内
 * @param {Object} element - 矩形元素
 * @param {Object} svgCanvas - SVG 画布元素
 */
const limitRectToSVG = (element, svgCanvas) => {
  // 定义矩形的最小宽度和高度
  const MIN_WIDTH = 10;
  const MIN_HEIGHT = 10;

  // 获取 SVG 画布尺寸
  const svgWidth = svgCanvas.clientWidth;
  const svgHeight = svgCanvas.clientHeight;

  // 获取矩形当前属性
  const x = element.x();
  const y = element.y();
  const width = element.width();
  const height = element.height();

  // 计算矩形四个顶点坐标
  const left = x;
  const top = y;
  const right = x + width;
  const bottom = y + height;

  // 边界检查与修正
  let newX = x;
  let newY = y;
  let newWidth = width;
  let newHeight = height;

  // 左边界
  if (left < 0) {
    newX = 0;
    newWidth = width + left;
  }

  // 上边界
  if (top < 0) {
    newY = 0;
    newHeight = height + top;
  }

  // 右边界
  if (right > svgWidth) {
    newWidth = svgWidth - newX;
  }

  // 下边界
  if (bottom > svgHeight) {
    newHeight = svgHeight - newY;
  }

  // 确保矩形宽度和高度不小于最小尺寸
  newWidth = Math.max(newWidth, MIN_WIDTH);
  newHeight = Math.max(newHeight, MIN_HEIGHT);

  // 调整 x 和 y 坐标以保证矩形不会超出右侧和底部边界
  if (newX + newWidth > svgWidth) {
    newX = svgWidth - newWidth;
  }
  if (newY + newHeight > svgHeight) {
    newY = svgHeight - newHeight;
  }

  // 应用修正后的属性
  if (newX !== x || newY !== y || newWidth !== width || newHeight !== height) {
    element.attr({
      x: newX,
      y: newY,
      width: newWidth,
      height: newHeight,
    });
  }
};
/**
 * 处理悬停预览
 * @param {{x: number, y: number}} pos - 当前鼠标位置
 */
const handleHoverPreview = (pos, ele = null) => {
  // 如果在绘制模式，不处理悬停效果
  if (drawingMode.value) {
    console.log("🎨 绘制模式下，不处理悬停预览");
    return;
  }
  // 如果正在绘制，不处理悬停效果
  if (drawing.value) {
    console.log("🎨 正在绘制中，不处理悬停预览");
    return;
  }

  // 如果正在拖拽或调整大小，不处理悬停效果
  // 拖拽过程中保持当前选择状态，不显示悬停效果
  if (dragging.value) return;

  // 不是手动指定矩形的情况下需要考虑
  if (!ele) {
    // 性能优化：增加悬停检测的稳定性
    // 检查鼠标位置是否发生显著变化
    const distance = Math.sqrt(
      (pos.x - lastMousePos.value.x) ** 2 + (pos.y - lastMousePos.value.y) ** 2
    );
    if (distance < 4) return; // 进一步增加最小移动距离，减少频繁切换
  }

  lastMousePos.value = pos;
  // console.log("ele---", ele);
  let element;
  if (ele) {
    element = ele;
  } else {
    element = findElementAtPosition(pos);
  }

  if (element) {
    element.front();
  }

  if (!element) {
    return;
  }

  // 清除之前的悬停状态
  if (hoveredElement.value && hoveredElement.value !== element) {
    // 如果当前悬停元素不是之前的元素且不在多选元素内,则恢复默认样式
    // if (
    //   operationType.value == 'batchSelect' &&
    //   !batchOperationRectKeyList.value.includes(element.data('elementId'))
    // ) {
    //   element.attr({
    //     stroke: getDefaultStroke(element),
    //     strokeWidth: 2,
    //     fill: getDefaultFill(element)
    //   })
    // }
    if (
      operationType.value == "batchSelect" &&
      !batchOperationRectKeyList.value.includes(
        hoveredElement.value.data("elementId") || operationType.value == "mouseSelect"
      )
    ) {
      hoveredElement.value.attr({
        stroke: getDefaultStroke(hoveredElement.value),
        strokeWidth: 2,
        fill: getDefaultFill(hoveredElement.value),
      });
    }

    // 重要：移出时不恢复拖拽状态，保持当前状态
    if (window.debugMode) {
      console.log("🔄 移出元素，保持拖拽状态");
    }
  }
  console.log("selectedElement.value66", selectedElement.value);
  console.log("element.value66", element);

  // 设置新的悬停状态 - 实现CVAT风格的"移入即选中"
  if (element && element !== selectedElement.value) {
    // 移入新矩形，立即选中
    if (hoveredElement.value !== element) {
      hoveredElement.value = element;

      // 非绘制模式下，移入就立即选中
      selectElement(element);

      // 重要：确保选中的元素有完整的拖拽功能
      if (element) {
        // 启用拖拽功能
        if (!element.draggable) {
          element.draggable(true);
          console.log("✅ 为移入元素启用拖拽功能:", element.type);
        }

        // 先移除所有可能存在的拖拽监听器
        element.off("dragstart dragmove dragend");

        // 重新绑定完整的拖拽事件监听器
        element.on("dragstart", () => {
          console.log("🎯 移入元素开始拖拽:", element.type);

          // 拖拽开始时，确保这个元素被选中
          if (selectedElement.value !== element) {
            selectElement(element);
          }

          dragging.value = true;
        });

        element.on("dragmove", () => {
          // 拖拽过程中，更新控制点位置
          if (selectedElement.value === element) {
            updateResizeHandlesPosition(element);
          }
        });

        element.on("dragend", () => {
          console.log("🎯 移入元素拖拽结束:", element.type);
          dragging.value = false;
          console.log("element", {
            x: element.x(),
            y: element.y(),
            width: element.width(),
            height: element.height(),
          });
          // 调用公共函数限制矩形在 SVG 区域内
          if (svgCanvas.value && element) {
            limitRectToSVG(element, svgCanvas.value);
          }

          // 拖拽结束后，更新控制点位置
          updateResizeHandlesPosition(element);

          updateRectData(element);
        });
      }
    }
  } else if (element && element === selectedElement.value) {
    // 如果悬停的是当前选中的元素，保持选中状态
    if (hoveredElement.value !== element) {
      hoveredElement.value = element;
    }
    selectElement(element);
  } else {
    // 如果没有悬停任何元素，保持当前选中状态（CVAT风格）
    // 不清除选择，只有移入其他矩形时才切换
    if (hoveredElement.value && hoveredElement.value !== selectedElement.value) {
      hoveredElement.value = null;
    }
  }
};

/**
 * 退出绘制模式
 */
const exitDrawingMode = () => {
  // 如果正在拖拽，不退出绘制模式
  if (dragging.value) {
    console.log("⚠️ 正在拖拽中，不退出绘制模式");
    return;
  }

  drawingMode.value = false;
  drawing.value = false;
  changeRectanglesDragStatus(true);
  if (currentElement.value) {
    // 如果正在绘制，取消当前绘制
    currentElement.value.remove();
    currentElement.value = null;
  }

  // 恢复默认鼠标样式
  restoreNormalCursor();

  // // 停止绘制模式鼠标样式监控
  if (window._cursorMonitorInterval) {
    clearInterval(window._cursorMonitorInterval);
    window._cursorMonitorInterval = null;
    console.log("✅ 绘制模式鼠标样式监控已停止");
  }

  // console.log("✅ 已退出绘制模式");
};

/**
 * 添加键盘事件监听器
 */
const addKeyboardListeners = () => {
  console.log("⌨️ 添加键盘事件监听器");

  // 监听键盘按下事件
  document.addEventListener("keydown", (event) => {
    const tag = currentMouseEvent.value?.target.tagName?.toLowerCase() || "";

    // 判断是否是 SVG 或它的子元素
    if (tag !== "svg" && currentMouseEvent.value?.target.ownerSVGElement == null) {
      return; // 不是 SVG 相关元素，直接退出
    }
    // 如果正在绘制或拖拽，不处理快捷键
    if (drawing.value || dragging.value) {
      console.log("⌨️ 正在绘制或拖拽中，跳过快捷键处理");
      return;
    }

    // 检查是否在SVG画布区域内
    if (!isMouseInSVGCanvas()) {
      console.log("⌨️ 鼠标不在SVG画布区域内，跳过快捷键处理");
      return;
    }

    switch (event.key.toLowerCase()) {
      // 两种绘制类型
      case settingMsg.value.readRangeMarker.key.toLowerCase(): // N键绘制矩形
      case settingMsg.value.unReadRangeMarker.key.toLowerCase(): // r键绘制矩形
        event.preventDefault();
        console.log("🎨 快捷键N：进入矩形绘制模式");
        if (
          event.key.toLowerCase() == settingMsg.value.readRangeMarker.key.toLowerCase()
        ) {
          rectType.value = "readRangeMarker";
          selectSettingMsg.value = settingMsg.value.readRangeMarker;
        } else {
          rectType.value = "unReadRangeMarker";
          selectSettingMsg.value = settingMsg.value.unReadRangeMarker;
        }
        selectShape("rect");
        break;

      case "escape": // ESC键退出绘制模式
        event.preventDefault();
        console.log("🚪 快捷键ESC：退出绘制模式");
        exitDrawingMode();
        break;
      case "z":
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          console.log("⌃Z 快捷键：执行撤销操作");
          undoLastAction();
        }
        break;
      case "c":
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          console.log("⌃c 快捷键：执行复制操作");
          copyElementHandle();
        }
        break;
      case "v":
        if (event.ctrlKey || event.metaKey) {
          event.preventDefault();
          console.log("⌃v 快捷键：执行黏贴操作");

          pasteElementHandle();
        }
        break;
      // case "space": // 空格键测试拖动
      //   event.preventDefault();
      //   console.log("🧪 快捷键空格：测试拖动");
      //   testPanning();
      //   break;
      case "delete": // Delete键删除选中的矩形
        event.preventDefault();
        console.log("🗑️ 快捷键Delete/Backspace：删除选中的矩形");
        deleteSelectedRectangle();
        break;
      default:
        console.log("⌨️ 未处理的按键:", event.key);
    }
  });
};

/**
 * 检查鼠标是否在SVG画布区域内
 */
const isMouseInSVGCanvas = () => {
  if (!svgCanvas.value) return false;

  const rect = svgCanvas.value.getBoundingClientRect();
  const mouseX = window.mouseX || 0; // 需要跟踪鼠标位置
  const mouseY = window.mouseY || 0;

  return (
    mouseX >= rect.left &&
    mouseX <= rect.right &&
    mouseY >= rect.top &&
    mouseY <= rect.bottom
  );
};

// 移除旧的快捷键绘制函数，现在使用点击绘制

/**
 * 应用视口变换
 */
const applyViewportTransform = () => {
  if (!svgDoc.value) return;

  // const svgElement = svgDoc.value.node;
  // svgElement.style.transform = `translate(${viewport.value.translateX}px, ${viewport.value.translateY}px) scale(${viewport.value.scale})`;
  // svgElement.style.transformOrigin = "50% 50%";

  // // 添加过渡效果，使缩放更平滑
  // svgElement.style.transition = "transform 0.1s ease-out";

  console.log("🔍 应用视口变换:", {
    scale: viewport.value.scale,
    translateX: viewport.value.translateX,
    translateY: viewport.value.translateY,
  });
};

/**
 * 处理滚轮缩放
 */
const handleWheel = (event) => {
  event.preventDefault();

  if (!svgCanvas.value) return;

  const rect = svgCanvas.value.getBoundingClientRect();
  const mouseX = event.clientX - rect.left;
  const mouseY = event.clientY - rect.top;

  // 计算缩放中心点（相对于SVG）
  const centerX = (mouseX - viewport.value.translateX) / viewport.value.scale;
  const centerY = (mouseY - viewport.value.translateY) / viewport.value.scale;

  // 计算缩放因子
  const delta = event.deltaY > 0 ? 0.9 : 1.1;
  const newScale = Math.max(
    viewport.value.minScale,
    Math.min(viewport.value.maxScale, viewport.value.scale * delta)
  );

  // 计算新的偏移量，保持鼠标位置不变
  const scaleRatio = newScale / viewport.value.scale;
  viewport.value.translateX = mouseX - centerX * newScale;
  viewport.value.translateY = mouseY - centerY * newScale;
  viewport.value.scale = newScale;

  // 应用边界限制，防止内容完全移出可视区域
  applyBoundaryConstraints();

  // 应用变换
  // applyViewportTransform();

  // 更新控制点位置
  if (selectedElement.value) {
    updateResizeHandlesPosition(selectedElement.value);
  }

  // 重要：缩放后重新激活绘制模式，确保事件监听器正常工作
  if (drawingMode.value) {
    console.log("🔄 缩放后重新激活绘制模式");
    reactivateDrawingMode();
  }
};

/**
 * 开始拖动画布
 */
const startPanning = (event) => {
  console.log("🎯 startPanning 被调用");

  if (drawing.value || drawingMode.value) {
    console.log("❌ 绘制模式下不允许拖动");
    return;
  }

  viewport.value.isPanning = true;
  viewport.value.lastPanPoint = { x: event.clientX, y: event.clientY };

  // 改变鼠标样式
  if (svgCanvas.value) {
    svgCanvas.value.style.cursor = "grabbing";
  }

  // 添加全局事件监听器
  document.addEventListener("mousemove", panCanvas);
  document.addEventListener("mouseup", stopPanning);
};

/**
 * 拖动画布
 */
const panCanvas = (event) => {
  if (!viewport.value.isPanning) {
    console.log("❌ 不在拖动状态");
    return;
  }

  const deltaX = event.clientX - viewport.value.lastPanPoint.x;
  const deltaY = event.clientY - viewport.value.lastPanPoint.y;

  viewport.value.translateX += deltaX;
  viewport.value.translateY += deltaY;
  viewport.value.lastPanPoint = { x: event.clientX, y: event.clientY };

  // 应用边界限制
  applyBoundaryConstraints();

  // 应用变换
  // applyViewportTransform()

  // 更新控制点位置
  if (selectedElement.value) {
    updateResizeHandlesPosition(selectedElement.value);
  }

  // 重要：拖动后重新激活绘制模式，确保事件监听器正常工作
  if (drawingMode.value) {
    console.log("🔄 拖动后重新激活绘制模式");
    reactivateDrawingMode();
  }
};

/**
 * 停止拖动画布
 */
const stopPanning = () => {
  console.log("🛑 stopPanning 被调用");

  viewport.value.isPanning = false;

  // 恢复鼠标样式
  if (svgCanvas.value) {
    svgCanvas.value.style.cursor = "default";
  }

  // 移除全局事件监听器
  document.removeEventListener("mousemove", panCanvas);
  document.removeEventListener("mouseup", stopPanning);

  console.log("✅ 拖动已停止，事件监听器已移除");
};
const loading = ref(true);

// 预加载图片以获取尺寸
const preloadImage = () => {
  return new Promise(async (resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      const naturalWidth = img.naturalWidth;
      const naturalHeight = img.naturalHeight;

      console.log("预加载图片尺寸:", {
        width: naturalWidth,
        height: naturalHeight,
      });

      if (naturalWidth && naturalHeight) {
        // 计算图片宽高比
        imageAspectRatio.value = naturalWidth / naturalHeight;

        // 根据图片比例调整画布尺寸，最长边适应容器
        // resolve({ width: naturalWidth, height: naturalHeight });
        adjustCanvasSizeToContainer(naturalWidth, naturalHeight);
        resolve();
        loading.value = false;
      } else {
        reject();
      }
    };

    img.onerror = (error) => {
      console.error("图片预加载失败:", error);
      // 使用默认尺寸
      canvasWidth.value = containerWidth.value;
      canvasHeight.value = containerHeight.value;
      reject(error);
    };

    // 处理不同情况
    let src = props.srcUrl;

    if (/^https?:\/\//.test(src)) {
      // ✅ 网络图片，直接用
      img.src = src;
    } else if (src.startsWith("@/")) {
      // ✅ assets 目录下，替换 @ 并用 new URL 解析
      const path = src.replace(/^@/, "/src");
      img.src = new URL(path, import.meta.url).href;
    } else {
      // ✅ public/ 下的图片或本地相对路径
      img.src = src;
    }
  });
};
const initImgScale = ref(null);
// 调整画布尺寸的函数 - 最长边适应容器
const adjustCanvasSizeToContainer = (imgWidth, imgHeight) => {
  const aspectRatio = imgWidth / imgHeight;

  let newWidth, newHeight;
  console.log("aspectRatio--", aspectRatio);

  // 计算图片在容器内的最大可用尺寸，保持宽高比
  const maxWidth = containerWidth.value;
  const maxHeight = containerHeight.value;

  // 计算缩放比例，取宽度和高度的缩放比例中的较小值
  const scaleX = maxWidth / imgWidth;
  const scaleY = maxHeight / imgHeight;
  const scale = Math.min(scaleX, scaleY);

  // 应用缩放比例计算新尺寸
  // newWidth = Math.round(imgWidth * scale);
  // newHeight = Math.round(imgHeight * scale);
  currentImageScale.value = scale;
  if (!initImgScale.value) {
    initImgScale.value = scale;
  }

  newWidth = imgWidth * scale;
  newHeight = imgHeight * scale;

  // 设置画布尺寸
  canvasWidth.value = newWidth;
  canvasHeight.value = newHeight;
  console.log("svgCanvas.value.parentElement--", svgCanvas.value?.parentElement);
  const actualWidth = svgCanvas.value?.parentElement.offsetWidth;
  const actualHeight = svgCanvas.value?.parentElement.offsetHeight;
  position.value = {
    x: (actualWidth - canvasWidth.value) / 2,
    y: (actualHeight - canvasHeight.value) / 2,
  };
};

// 更新视口边界限制
// const updateViewportBoundaries = () => {
//   // 更新视口的最小和最大边界
//   const svgWidth = canvasWidth.value
//   const svgHeight = canvasHeight.value

//   // 计算缩放后的SVG尺寸
//   const scaledWidth = svgWidth * viewport.value.scale
//   const scaledHeight = svgHeight * viewport.value.scale

//   // 限制X轴偏移
//   const maxTranslateX = containerWidth.value * 0.5
//   const minTranslateX = -(scaledWidth - containerWidth.value * 0.9)

//   viewport.value.translateX = Math.max(
//     minTranslateX,
//     Math.min(maxTranslateX, viewport.value.translateX)
//   )

//   // 限制Y轴偏移
//   const maxTranslateY = containerHeight.value * 0.5
//   const minTranslateY = -(scaledHeight - containerHeight.value * 0.9)

//   viewport.value.translateY = Math.max(
//     minTranslateY,
//     Math.min(maxTranslateY, viewport.value.translateY)
//   )
// }

// 修改现有的applyBoundaryConstraints函数
const applyBoundaryConstraints = () => {
  if (!svgCanvas.value) return;

  // 基于容器尺寸计算边界
  const svgWidth = containerWidth.value;
  const svgHeight = containerHeight.value;

  // 计算缩放后的SVG尺寸
  const scaledWidth = svgWidth * viewport.value.scale;
  const scaledHeight = svgHeight * viewport.value.scale;

  // 限制X轴偏移，确保至少有一部分内容可见
  const maxTranslateX = containerWidth.value * 0.5;
  const minTranslateX = -(scaledWidth - containerWidth.value * 0.9);

  viewport.value.translateX = Math.max(
    minTranslateX,
    Math.min(maxTranslateX, viewport.value.translateX)
  );

  // 限制Y轴偏移
  const maxTranslateY = containerHeight.value * 0.5;
  const minTranslateY = -(scaledHeight - containerHeight.value * 0.9);

  viewport.value.translateY = Math.max(
    minTranslateY,
    Math.min(maxTranslateY, viewport.value.translateY)
  );

  console.log("🔒 应用边界限制:", {
    translateX: viewport.value.translateX,
    translateY: viewport.value.translateY,
    scaledWidth,
    scaledHeight,
    canvasSize: { width: canvasWidth.value, height: canvasHeight.value },
    containerSize: {
      width: containerWidth.value,
      height: containerHeight.value,
    },
  });
};

/**
 * 重置视口
 */
const resetViewport = () => {
  //  position.value.x = 0
  // position.value.y = 0
  const actualWidth = svgCanvas.value?.parentElement.offsetWidth;
  const actualHeight = svgCanvas.value?.parentElement.offsetHeight;
  position.value = {
    x: (actualWidth - canvasWidth.value) / 2,
    y: (actualHeight - canvasHeight.value) / 2,
  };
  scale.value = 1;
  nextTick(() => {
    updateTooltip();
  });
};
// 计算按下画布的起始位置
const startX = ref(0);
const startY = ref(0);
const DRAG_THRESHOLD = 4;
/**
 * 鼠标按下事件处理
 */
const onMouseDown = (event) => {
  // debugger
  isSvgMouseDown.value = true;
  isSvgDragging.value = false;
  startX.value = event.clientX;
  startY.value = event.clientY;
};

function isRectAtPosition(event) {
  const rects = svgDoc.value?.node?.getElementsByTagName("rect");

  // 获取点击位置在SVG坐标系中的坐标
  const clickX = (event.clientX - viewport.value.translateX) / viewport.value.scale;
  const clickY = (event.clientY - viewport.value.translateY) / viewport.value.scale;

  return Array.from(rects).some((rect) => {
    const rectX = parseFloat(rect.getAttribute("x"));
    const rectY = parseFloat(rect.getAttribute("y"));
    const rectWidth = parseFloat(rect.getAttribute("width"));
    const rectHeight = parseFloat(rect.getAttribute("height"));

    return (
      clickX >= rectX &&
      clickX <= rectX + rectWidth &&
      clickY >= rectY &&
      clickY <= rectY + rectHeight
    );
  });
}
// 获取当前点击位置的矩形元素
function getRectAtPosition(pos) {
  const elementsAtPosition = [];

  // 找到所有包含该点的元素
  for (let i = 0; i < allElements.value.length; i++) {
    const element = allElements.value[i];
    if (isPointInElement(pos, element)) {
      // console.log("element--------", element);
      const area = calculateElementArea(element);
      elementsAtPosition.push({
        element: element,
        index: i,
        area: area,
        type: element.type,
      });
    }
  }
  console.log("elementsAtPosition--", elementsAtPosition);
  if (elementsAtPosition.length === 0) {
    return null;
  }

  if (elementsAtPosition.length === 1) {
    return elementsAtPosition[0].element;
  }

  // 多个元素重叠时，优先选择面积最小的（最精确的标注）
  // 性能优化：减少日志输出，只在调试时显示
  if (window.debugMode) {
    console.log(`找到 ${elementsAtPosition.length} 个重叠元素，开始智能排序...`);
  }

  // 按面积排序，面积越小优先级越高
  elementsAtPosition.sort((a, b) => {
    const areaDiff = a.area - b.area;

    // 面积差异大于10时，按面积排序（增加阈值，减少频繁切换）
    if (Math.abs(areaDiff) > 10) {
      if (window.debugMode) {
        console.log(`面积差异较大，按面积排序`);
      }
      return areaDiff;
    }

    // 面积相近时，按绘制顺序排序，后绘制的优先
    if (window.debugMode) {
      console.log(`面积相近，按绘制顺序排序`);
    }
    return b.index - a.index;
  });

  const selected = elementsAtPosition[0];
  if (window.debugMode) {
    console.log(
      `最终选择: ${selected.type}, 面积=${selected.area.toFixed(2)}, 索引=${
        selected.index
      }`
    );
  }

  return selected.element;
}

function handlerBatchRectList(item) {
  const rectElement = allElements.value.find((ele) => ele.data("elementId") == item.id);
  if (rectElement) {
    const elementId = rectElement.data("elementId");
    const rect = rectList.value.find((item) => item.id == elementId);
    if (batchOperationRectList.value.has(elementId)) {
      batchOperationRectList.value.delete(elementId);
      rectElement.attr({
        fill: getDefaultFill(rectElement),
      });
    } else {
      rectElement.attr({
        fill: getDefaultFill(rectElement, settingMsg.value.batchOpacity),
      });
      batchOperationRectList.value.set(elementId, rect);
    }
  }
}
/**
 * 鼠标松开事件处理
 */
const onMouseUp = (event) => {
  if (isSvgMouseDown.value && !isSvgDragging.value) {
    // 触发选中操作
    console.log("触发选中操作");

    // 只处理批量选择
    if (operationType.value == "batchSelect") {
      console.log("event---", event);
      const mousePosition = getMousePosition(event);
      const rectElement = getRectAtPosition(mousePosition);
      console.log("rect11--", rectElement);
      if (rectElement) {
        const elementId = rectElement.data("elementId");
        const rect = rectList.value.find((item) => item.id == elementId);
        if (batchOperationRectList.value.has(elementId)) {
          batchOperationRectList.value.delete(elementId);
          rectElement.attr({
            fill: getDefaultFill(rectElement),
          });
        } else {
          rectElement.attr({
            fill: getDefaultFill(rectElement, settingMsg.value.batchOpacity),
          });
          batchOperationRectList.value.set(elementId, rect);
        }
      }
    }
  }

  // 停止拖动画布
  if (viewport.value.isPanning) {
    console.log("🛑 在onMouseUp中停止拖动");
    stopPanning();
    return;
  }

  // 在点击绘制模式下，不调用stopDrawing，避免干扰点击绘制
  if (drawingMode.value && currentShape.value === "rect") {
    console.log("🎨 矩形点击绘制模式，跳过鼠标松开处理");
    return;
  }
};
const rectList = computed({
  get() {
    console.log("props.data--", props.data);

    return props.data;
  },
  set(val) {
    console.log("设置rectList.value--", val);

    emits("update:data", val);
  },
});
// 初始化矩形的绘制
const initRectList = () => {
  console.log("触发initRectList1");
  rectList.value = rectList.value.map((item) => {
    return {
      ...item,
      x: item.x * currentImageScale.value,
      y: item.y * currentImageScale.value,
      width: item.width * currentImageScale.value,
      height: item.height * currentImageScale.value,
    };
  });

  console.log("currentImageScale.value--", currentImageScale.value);
  console.log("rectList.value--", rectList.value);

  nextTick(() => {
    rectList.value.forEach((item) => {
      const rect = svgDoc.value.rect(item.width, item.height);

      rect
        .attr({
          x: item.x,
          y: item.y,
          id: item.id,
          fill: hexToRgb(settingMsg.value[item.rectType].fill),
          stroke: settingMsg.value[item.rectType].fill,
          strokeWidth: 1,
        })
        .style("cursor", "move"); // 恢复拖拽功能;
      rect.draggable(true);
      rect.type = "rect";
      rect.data("elementId", item.id);
      allElements.value.push(rect);
    });
  });
};

// 用于控制是否触发更新的标志位
let isInitializing = true;

// 监听 rectList 的变化
watch(
  [rectList, loading],
  (newData) => {
    if (isInitializing) {
      if (newData[0] && newData[0].length > 0 && svgDoc.value && !newData[1]) {
        console.log("去调取了");

        isInitializing = false;
        initRectList();
      }
    }
  },
  {
    immediate: true,
  }
);
const imageOrigin = ref("50% 50%");
const initialDistance = ref(0);
const svgStyle = computed(() => {
  return {
    position: "absolute",
    left: "0",
    top: "0",

    transform: `scale(${scale.value}) translate(${position.value.x / scale.value}px, ${
      position.value.y / scale.value
    }px)`,
    // transform: `translate(${position.value.x }px, ${position.value.y }px)`,

    opacity: 1,
    transformOrigin: imageOrigin.value,
    cursor: containerDragging.value ? "grabbing" : "",
  };
});

const scale = ref(1); // 默认缩放级别为1，即100%

const isDraggingNow = ref(false);
const containerDragging = ref(false);
const clickThreshold = ref(5);
const position = ref({ x: 0, y: 0 });
let start = { x: 0, y: 0 };

const resetSvg = () => {
  position.value.x = 0;
  position.value.y = 0;
  scale.value = 1;
};

const startDrag = (event) => {
  isDraggingNow.value = false;
  if (event.touches && event.touches.length === 2) {
    initialDistance.value = Math.hypot(
      event.touches[0].pageX - event.touches[1].pageX,
      event.touches[0].pageY - event.touches[1].pageY
    );
  } else {
    containerDragging.value = true;
    start.x = event.type.includes("touch") ? event.touches[0].clientX : event.clientX;
    start.y = event.type.includes("touch") ? event.touches[0].clientY : event.clientY;
  }

  event.preventDefault();
};

const onDrag = (event) => {
  if (drawingMode.value) {
    return;
  }

  if (event.touches && event.touches.length === 2) {
    const currentDistance = Math.hypot(
      event.touches[0].pageX - event.touches[1].pageX,
      event.touches[0].pageY - event.touches[1].pageY
    );

    if (currentDistance > initialDistance.value) {
      // 放大图片
      scale.value += 0.1;
    } else if (currentDistance < initialDistance.value) {
      // 缩小图片
      scale.value -= 0.1;
    }
    initialDistance.value = currentDistance;
  } else {
    if (containerDragging.value) {
      const currentX = event.type.includes("touch")
        ? event.touches[0].clientX
        : event.clientX;
      const currentY = event.type.includes("touch")
        ? event.touches[0].clientY
        : event.clientY;
      const dx = currentX - start.x;
      const dy = currentY - start.y;
      if (Math.abs(dx) > clickThreshold.value || Math.abs(dy) > clickThreshold.value) {
        isDraggingNow.value = true;
        position.value.x += dx;
        position.value.y += dy;
        start.x = currentX;
        start.y = currentY;

        // console.log(" position.value------", position.value);
      }
    }
  }
  nextTick(() => {
    updateTooltip();
  });
};

const endDrag = () => {
  containerDragging.value = false;
  initialDistance.value = 0;
};

const onWheel = (event) => {
  event.preventDefault();
  if (event.deltaY < 0) {
    scale.value = Math.min(scale.value * 1.1, 5.0);
    // scale.value *= 1.1
  } else {
    scale.value = Math.max(scale.value / 1.1, 0.5);
    // scale.value /= 1.1
  }
  nextTick(() => {
    updateTooltip();
  });
};
const changeScale = (type) => {
  scale.value =
    type == "magnify"
      ? Math.min(scale.value * 1.1, 5.0)
      : Math.max(scale.value / 1.1, 0.5);
  nextTick(() => {
    updateTooltip();
  });
};

// 更新容器宽高的函数
const updateContainerSize = async () => {
  console.log("containerRef.value--", containerRef.value);
  console.log("containerRef.value.clientWidth--", containerRef.value?.clientWidth);

  if (containerRef.value) {
    containerWidth.value = containerRef.value.clientWidth;
    containerHeight.value = containerRef.value.clientHeight;
  }
  await preloadImage();

  if (svgDoc.value && rectList.value && rectList.value.length > 0) {
    rectList.value = rectList.value.map((item) => {
      return {
        ...item,
        x: (item.x / initImgScale.value) * currentImageScale.value,

        y: (item.y / initImgScale.value) * currentImageScale.value,
        width: (item.width / initImgScale.value) * currentImageScale.value,
        height: (item.height / initImgScale.value) * currentImageScale.value,
      };
    });

    allElements.value.forEach((ele) => {
      ele.attr({
        x: (ele.attr("x") / initImgScale.value) * currentImageScale.value,
        y: (ele.attr("y") / initImgScale.value) * currentImageScale.value,
        width: (ele.attr("width") / initImgScale.value) * currentImageScale.value,
        height: (ele.attr("height") / initImgScale.value) * currentImageScale.value,
      });
    });

    initImgScale.value = currentImageScale.value;
  }
  // 初始化视口变换
};
// ==================== 生命周期钩子 ====================
let cleanupInterval = null;
const resizeObserver = ref();

// 当前鼠标在svg的坐标
const currentMouseSvgPosition = ref(null);
const currentMouseEvent = ref(null);
const getCurrentMouseSvgPosition = (event) => {
  currentMouseSvgPosition.value = getMousePosition(event);
  currentMouseEvent.value = event;
};

/**
 * 组件挂载后的初始化
 */
onMounted(async () => {
  // 注册鼠标事件
  document.addEventListener("click", (event) => {
    console.log("click", event);
  });
  document.addEventListener("mousemove", getCurrentMouseSvgPosition);
  resizeObserver.value = new ResizeObserver(updateContainerSize);
  if (containerRef.value) {
    resizeObserver.value.observe(containerRef.value);
    await updateContainerSize();
  }
  // 验证SVG.js插件加载状态
  validateSVGPlugins();
  // 预加载图片以获取尺寸
  await preloadImage();
  console.log("这里加载好了");

  try {
    svgDoc.value = SVG(svgCanvas.value);

    // 如果此时已有数据且是初始化阶段，执行初始化操作
    if (rectList.value && rectList.value.length > 0 && isInitializing) {
      isInitializing = false;
      initRectList();
    }
  } catch (error) {
    console.error("❌ SVG.js 初始化失败:", error);
  }

  // 初始化视口变换
  // applyViewportTransform()

  // 添加键盘事件监听器
  addKeyboardListeners();

  // 添加拖拽选择优化功能到全局
  window.optimizeDragSelection = optimizeDragSelection;

  // 在组件卸载时清理定时器

  console.log("🚀 onMounted 执行完成");
});
onUnmounted(() => {
  cleanupInterval && clearInterval(cleanupInterval);
  document.removeEventListener("mousemove", getCurrentMouseSvgPosition);
});

/**
 * 优化拖拽过程中的选择状态
 * 确保拖拽的元素始终被正确选中
 */
const optimizeDragSelection = () => {
  if (dragging.value && currentElement.value) {
    // 如果正在拖拽且当前元素存在，确保它被选中
    if (selectedElement.value !== currentElement.value) {
      selectElement(currentElement.value);
    }
  }
};

defineExpose({
  undoLastAction,
  cancelUndo,
  historyOperationList,
  handleHoverPreview,
  hoveredElement,
  allElements,
  // resetSvg
  resetViewport,
  clearBatchOperationRectList,
  handlerBatchRectList,
  removeElement,
  changeScale,
});
</script>

<style lang="scss" scoped>
.annotation-container {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  // gap: 20px;
  width: 100%;
  height: 100%;
  padding: 24px 24px 0;
  background: #f5f5f5;
  // min-width: 900px;
}

.annotation-svg-container {
  position: relative;
  // border: 2px solid #ddd;
  // border-radius: 8px;
  overflow: hidden;
  // background-color: #f8f9fa;
  // box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: border-color 0.3s ease, width 0.3s ease, height 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.annotation-svg-container:hover {
  /* border-color: #007bff; */
}

.annotation-svg-container svg {
  display: block;
  /* width: 100%;
  height: 100%; */
}

.controls {
  margin-top: 10px;
}

button {
  margin-right: 10px;
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* SVG调整大小控制点的鼠标样式 */
:deep(.svg-resize-handle) {
  cursor: pointer;
}

/* 角落控制点 - 对角线调整 */
:deep(.svg-resize-handle.nw) {
  cursor: nw-resize;
}

:deep(.svg-resize-handle.ne) {
  cursor: ne-resize;
}

:deep(.svg-resize-handle.sw) {
  cursor: sw-resize;
}

:deep(.svg-resize-handle.se) {
  cursor: se-resize;
}

/* 边缘控制点 - 单向调整 */
:deep(.svg-resize-handle.n) {
  cursor: n-resize;
}

:deep(.svg-resize-handle.s) {
  cursor: s-resize;
}

:deep(.svg-resize-handle.e) {
  cursor: e-resize;
}

:deep(.svg-resize-handle.w) {
  cursor: w-resize;
}

/* 拖拽时的鼠标样式 */
:deep(.svg-draggable) {
  cursor: move;
}

/* 选中状态下的鼠标样式 */
:deep(.svg-selected) {
  cursor: default;
}

/* 悬停状态下的鼠标样式 */
:deep(.svg-hover) {
  cursor: pointer;
}

/* 自定义缩放控制点样式 */
.resize-handle {
  pointer-events: all;
  z-index: 1000;
}

.resize-handle:hover {
  fill: #ff6b6b !important;
  stroke: #ff6b6b !important;
}

/* 快捷键信息样式 */
.shortcuts-info {
  margin-top: 10px;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 5px;
  border: 1px solid #e9ecef;
}

.shortcuts-info p {
  margin: 0;
  font-size: 14px;
  color: #6c757d;
}

.shortcuts-info kbd {
  background-color: #e9ecef;
  border: 1px solid #adb5bd;
  border-radius: 3px;
  padding: 2px 6px;
  font-size: 12px;
  font-family: monospace;
}

.reset-btn {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 12px;
  cursor: pointer;
  margin-left: 5px;
}

.reset-btn:hover {
  background-color: #0056b3;
}

/* ... existing code ... */

/* 添加样式用于JSON数据显示区域 */
.rect-data-display {
  flex: 1;
  margin: 20px;
  padding: 15px;
  /* background-color: #f5f5f5; */
  background-color: red;
  border-radius: 8px;
  max-height: 300px;
  overflow-y: auto;
}

.rect-data-display pre {
  font-family: monospace;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.rect-item {
  padding: 20px;
  border: 1px solid #eee;
  &.active {
    border: 1px solid yellow;
  }
}

.tooltip {
  position: absolute;
  // background: rgba(0, 0, 0, 0.7);
  // color: white;
  // padding: 4px 8px;
  border-radius: 4px;
  font-size: 15px;
  pointer-events: none;
  z-index: 11;

  transform: translate(0, -100%);
  // color: red;
  max-width: 200px;
  word-break: break-word;
  white-space: pre-wrap;
  text-shadow: 0 0 2px rgba(0, 0, 0, 0.7), 0 1px 3px rgba(0, 0, 0, 0.5);
}
</style>
